diff --git a/example/adaptive_threshold.cpp b/example/adaptive_threshold.cpp index 6d953808d7..65f0f9ac14 100644 --- a/example/adaptive_threshold.cpp +++ b/example/adaptive_threshold.cpp @@ -7,6 +7,7 @@ // #include #include +#include using namespace boost::gil; @@ -16,14 +17,17 @@ int main() read_image("test_adaptive.png", img, png_tag{}); gray8_image_t img_out(img.dimensions()); - // performing binary threshold on each channel of the image - // if the pixel value is more than 150 than it will be set to 255 else to 0 - boost::gil::threshold_adaptive(const_view(img), view(img_out), 11); - write_view("out-threshold-adaptive.png", view(img_out), png_tag{}); + boost::gil::threshold_adaptive(const_view(img), view(img_out), 11, threshold_adaptive_method::mean, threshold_direction::regular, 2); + write_view("out-threshold-adaptive-mean.png", view(img_out), png_tag{}); + + boost::gil::threshold_adaptive(const_view(img), view(img_out), 11, threshold_adaptive_method::mean, threshold_direction::inverse, 2); + write_view("out-threshold-adaptive-mean-inv.png", view(img_out), png_tag{}); - // if the pixel value is more than 150 than it will be set to 150 else no change - boost::gil::threshold_adaptive(const_view(img), view(img_out), 11, threshold_adaptive_method::mean, threshold_direction::inverse); - write_view("out-threshold-adaptive-inv.png", view(img_out), png_tag{}); + boost::gil::threshold_adaptive(const_view(img), view(img_out), 7, threshold_adaptive_method::gaussian, threshold_direction::regular, 2); + write_view("out-threshold-adaptive-gaussian.png", view(img_out), png_tag{}); + + boost::gil::threshold_adaptive(const_view(img), view(img_out), 11, threshold_adaptive_method::gaussian, threshold_direction::inverse, 2); + write_view("out-threshold-adaptive-gaussian-inv.png", view(img_out), png_tag{}); return 0; } diff --git a/example/test_adaptive.png b/example/test_adaptive.png index 8aea767ab8..d72dd68f7b 100644 Binary files a/example/test_adaptive.png and b/example/test_adaptive.png differ diff --git a/include/boost/gil/image_processing/threshold.hpp b/include/boost/gil/image_processing/threshold.hpp index 0a4f579499..7bb39b9874 100644 --- a/include/boost/gil/image_processing/threshold.hpp +++ b/include/boost/gil/image_processing/threshold.hpp @@ -16,10 +16,12 @@ #include #include +#include + #include #include #include -#include +#include namespace boost { namespace gil { @@ -403,31 +405,49 @@ void threshold_adaptive typedef typename channel_type::type source_channel_t; typedef typename channel_type::type result_channel_t; + image temp_img(src_view.width(), src_view.height()); + typename image::view_t temp_view = view(temp_img); + SrcView temp_conv(temp_view); + if (method == threshold_adaptive_method::mean) { std::vector mean_kernel_values(kernel_size, 1.0f/kernel_size); kernel_1d kernel(mean_kernel_values.begin(), kernel_size, kernel_size/2); - image temp_img(src_view.width(), src_view.height()); - typename image::view_t temp_view = view(temp_img); - SrcView temp_conv(temp_view); - convolve_1d>( src_view, kernel, temp_view ); + } + else if (method == threshold_adaptive_method::gaussian) + { + gray32f_image_t gaussian_kernel_values(kernel_size, kernel_size); + generate_gaussian_kernel(view(gaussian_kernel_values), 1.0); + + gray32f_view_t gaussian_kernel_view = view(gaussian_kernel_values); + kernel_2d kernel( + kernel_size, + kernel_size / 2, + kernel_size / 2 + ); - if (direction == threshold_direction::regular) - { - detail::adaptive_impl(src_view, temp_conv, dst_view, - [max_value, constant](source_channel_t px, source_channel_t threshold) -> result_channel_t - { return px > (threshold - constant) ? max_value : 0; }); - } - else - { - detail::adaptive_impl(src_view, temp_conv, dst_view, - [max_value, constant](source_channel_t px, source_channel_t threshold) -> result_channel_t - { return px > (threshold - constant) ? 0 : max_value; }); - } + std::transform(gaussian_kernel_view.begin(), gaussian_kernel_view.end(), kernel.begin(), + [](gray32f_pixel_t pixel) -> float {return pixel.at(std::integral_constant{}); } + ); + + convolve_2d(src_view, kernel, temp_view); + } + + if (direction == threshold_direction::regular) + { + detail::adaptive_impl(src_view, temp_conv, dst_view, + [max_value, constant](source_channel_t px, source_channel_t threshold) -> result_channel_t + { return px > (threshold - constant) ? max_value : 0; }); + } + else + { + detail::adaptive_impl(src_view, temp_conv, dst_view, + [max_value, constant](source_channel_t px, source_channel_t threshold) -> result_channel_t + { return px > (threshold - constant) ? 0 : max_value; }); } }