8 #ifndef BOOST_GIL_IMAGE_PROCESSING_THRESHOLD_HPP     9 #define BOOST_GIL_IMAGE_PROCESSING_THRESHOLD_HPP    13 #include <type_traits>    19 #include <boost/assert.hpp>    21 #include <boost/gil/image.hpp>    22 #include <boost/gil/extension/numeric/kernel.hpp>    23 #include <boost/gil/extension/numeric/convolve.hpp>    24 #include <boost/gil/image_processing/numeric.hpp>    26 namespace boost { 
namespace gil {
    32     typename SourceChannelT,
    33     typename ResultChannelT,
    38 void threshold_impl(SrcView 
const& src_view, DstView 
const& dst_view, Operator 
const& threshold_op)
    40     gil_function_requires<ImageViewConcept<SrcView>>();
    41     gil_function_requires<MutableImageViewConcept<DstView>>();
    42     static_assert(color_spaces_are_compatible
    44         typename color_space_type<SrcView>::type,
    45         typename color_space_type<DstView>::type
    46     >::value, 
"Source and destination views must have pixels with the same color space");
    49     for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
    51         typename SrcView::x_iterator src_it = src_view.row_begin(y);
    52         typename DstView::x_iterator dst_it = dst_view.row_begin(y);
    54         for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
    56             static_transform(src_it[x], dst_it[x], threshold_op);
    90 enum class threshold_adaptive_method
   107 template <
typename SrcView, 
typename DstView>
   109     SrcView 
const& src_view,
   110     DstView 
const& dst_view,
   122         detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
   123             [threshold_value, max_value](source_channel_t px) -> result_channel_t {
   124                 return px > threshold_value ? max_value : 0;
   129         detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
   130             [threshold_value, max_value](source_channel_t px) -> result_channel_t {
   131                 return px > threshold_value ? 0 : max_value;
   146 template <
typename SrcView, 
typename DstView>
   148     SrcView 
const& src_view,
   149     DstView 
const& dst_view,
   157     result_channel_t max_value = (std::numeric_limits<result_channel_t>::max)();
   158     threshold_binary(src_view, dst_view, threshold_value, max_value, direction);
   172 template <
typename SrcView, 
typename DstView>
   174     SrcView 
const& src_view,
   175     DstView 
const& dst_view,
   185     std::function<result_channel_t(source_channel_t)> threshold_logic;
   191             detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
   192                 [threshold_value](source_channel_t px) -> result_channel_t {
   193                     return px > threshold_value ? threshold_value : px;
   198             detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
   199                 [threshold_value](source_channel_t px) -> result_channel_t {
   200                     return px > threshold_value ? px : threshold_value;
   208             detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
   209                 [threshold_value](source_channel_t px) -> result_channel_t {
   210                     return px > threshold_value ? px : 0;
   215             detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
   216                 [threshold_value](source_channel_t px) -> result_channel_t {
   217                     return px > threshold_value ? 0 : px;
   225 template <
typename SrcView, 
typename DstView>
   226 void otsu_impl(SrcView 
const& src_view, DstView 
const& dst_view, 
threshold_direction direction)
   229     using source_channel_t = 
typename channel_type<SrcView>::type;
   231     std::array<std::size_t, 256> histogram{};
   234     auto min = (std::numeric_limits<source_channel_t>::max)(),
   235         max = (std::numeric_limits<source_channel_t>::min)();
   237     if (
sizeof(source_channel_t) > 1 || std::is_signed<source_channel_t>::value)
   240         for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
   242             typename SrcView::x_iterator src_it = src_view.row_begin(y);
   243             for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
   245                 if (src_it[x] < min) min = src_it[x];
   246                 if (src_it[x] > min) min = src_it[x];
   251         for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
   253             typename SrcView::x_iterator src_it = src_view.row_begin(y);
   255             for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
   257                 histogram[((src_it[x] - min) * 255) / (max - min)]++;
   264         for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
   266             typename SrcView::x_iterator src_it = src_view.row_begin(y);
   268             for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
   270                 histogram[src_it[x]]++;
   286     std::ptrdiff_t total_pixel = src_view.height() * src_view.width();
   287     std::ptrdiff_t sum_total = 0, sum_back = 0;
   288     std::size_t weight_back = 0, weight_fore = 0, 
threshold = 0;
   289     double var_max = 0, mean_back, mean_fore, var_intra_class;
   291     for (std::size_t t = 0; t < 256; t++)
   293         sum_total += t * histogram[t];
   296     for (
int t = 0; t < 256; t++)
   298         weight_back += histogram[t];               
   299         if (weight_back == 0) 
continue;
   301         weight_fore = total_pixel - weight_back;          
   302         if (weight_fore == 0) 
break;
   304         sum_back += t * histogram[t];
   306         mean_back = sum_back / weight_back;            
   307         mean_fore = (sum_total - sum_back) / weight_fore;    
   310         var_intra_class = weight_back * weight_fore * (mean_back - mean_fore) * (mean_back - mean_fore);
   313         if (var_intra_class > var_max) {
   314             var_max = var_intra_class;
   318     if (
sizeof(source_channel_t) > 1 && std::is_unsigned<source_channel_t>::value)
   328 template <
typename SrcView, 
typename DstView>
   329 void threshold_optimal
   331     SrcView 
const& src_view,
   332     DstView 
const& dst_view,
   339         for (std::size_t i = 0; i < src_view.num_channels(); i++)
   342                 (nth_channel_view(src_view, i), nth_channel_view(dst_view, i), direction);
   351     typename SourceChannelT,
   352     typename ResultChannelT,
   359     SrcView 
const& src_view,
   360     SrcView 
const& convolved_view,
   361     DstView 
const& dst_view,
   362     Operator 
const& threshold_op
   366     gil_function_requires<ImageViewConcept<SrcView>>();
   367     gil_function_requires<MutableImageViewConcept<DstView>>();
   369     static_assert(color_spaces_are_compatible
   371         typename color_space_type<SrcView>::type,
   372         typename color_space_type<DstView>::type
   373     >::value, 
"Source and destination views must have pixels with the same color space");
   376     for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
   378         typename SrcView::x_iterator src_it = src_view.row_begin(y);
   379         typename SrcView::x_iterator convolved_it = convolved_view.row_begin(y);
   380         typename DstView::x_iterator dst_it = dst_view.row_begin(y);
   382         for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
   384             static_transform(src_it[x], convolved_it[x], dst_it[x], threshold_op);
   390 template <
typename SrcView, 
typename DstView>
   391 void threshold_adaptive
   393     SrcView 
const& src_view,
   394     DstView 
const& dst_view,
   395     typename channel_type<DstView>::type max_value,
   396     std::size_t kernel_size,
   397     threshold_adaptive_method method = threshold_adaptive_method::mean,
   399     typename channel_type<DstView>::type constant = 0
   402     BOOST_ASSERT_MSG((kernel_size % 2 != 0), 
"Kernel size must be an odd number");
   404     typedef typename channel_type<SrcView>::type source_channel_t;
   405     typedef typename channel_type<DstView>::type result_channel_t;
   407     image<typename SrcView::value_type> temp_img(src_view.width(), src_view.height());
   408     typename image<typename SrcView::value_type>::view_t temp_view = 
view(temp_img);
   409     SrcView temp_conv(temp_view);
   411     if (method == threshold_adaptive_method::mean)
   413         std::vector<float> mean_kernel_values(kernel_size, 1.0f/kernel_size);
   414         kernel_1d<float> kernel(mean_kernel_values.begin(), kernel_size, kernel_size/2);
   418             pixel<float, typename SrcView::value_type::layout_t>
   419         >(src_view, kernel, temp_view);
   421     else if (method == threshold_adaptive_method::gaussian)
   424         convolve_2d(src_view, kernel, temp_view);
   429         detail::adaptive_impl<source_channel_t, result_channel_t>(src_view, temp_conv, dst_view,
   430             [max_value, constant](source_channel_t px, source_channel_t threshold) -> result_channel_t
   431         { 
return px > (
threshold - constant) ? max_value : 0; });
   435         detail::adaptive_impl<source_channel_t, result_channel_t>(src_view, temp_conv, dst_view,
   436             [max_value, constant](source_channel_t px, source_channel_t threshold) -> result_channel_t
   437         { 
return px > (
threshold - constant) ? 0 : max_value; });
   441 template <
typename SrcView, 
typename DstView>
   442 void threshold_adaptive
   444     SrcView 
const& src_view,
   445     DstView 
const& dst_view,
   446     std::size_t kernel_size,
   447     threshold_adaptive_method method = threshold_adaptive_method::mean,
   453     typedef typename channel_type<DstView>::type result_channel_t;
   455     result_channel_t max_value = (std::numeric_limits<result_channel_t>::max)();
   457     threshold_adaptive(src_view, dst_view, max_value, kernel_size, method, direction, constant);
   464 #endif //BOOST_GIL_IMAGE_PROCESSING_THRESHOLD_HPP void threshold_binary(SrcView const &src_view, DstView const &dst_view, typename channel_type< DstView >::type threshold_value, threshold_direction direction=threshold_direction::regular)
Applies fixed threshold to each pixel of image view. Performs image binarization by thresholding chan...
Definition: threshold.hpp:147
threshold_truncate_mode
TODO.
Definition: threshold.hpp:84
threshold_direction
Definition: threshold.hpp:69
threshold_optimal_value
Method of optimal threshold value calculation.
Definition: threshold.hpp:77
Consider values less than or equal to threshold value.
Definition: color_convert.hpp:31
const image< Pixel, IsPlanar, Alloc >::view_t & view(image< Pixel, IsPlanar, Alloc > &img)
Returns the non-constant-pixel view of an image.
Definition: image.hpp:443
void threshold_truncate(SrcView const &src_view, DstView const &dst_view, typename channel_type< DstView >::type threshold_value, threshold_truncate_mode mode=threshold_truncate_mode::threshold, threshold_direction direction=threshold_direction::regular)
Applies truncating threshold to each pixel of image view. Takes an image view and performes truncatin...
Definition: threshold.hpp:173
Consider values greater than threshold value.
detail::kernel_2d< T, Allocator > generate_gaussian_kernel(std::size_t side_length, double sigma)
Generate Gaussian kernelFills supplied view with values taken from Gaussian distribution....
Definition: numeric.hpp:120