Skip to content

Commit

Permalink
added definition of gaussian adaptive threshold (#379)
Browse files Browse the repository at this point in the history
closes #316
  • Loading branch information
miralshah365 committed Aug 19, 2019
1 parent f6c502b commit 5f612cc
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 24 deletions.
18 changes: 11 additions & 7 deletions example/adaptive_threshold.cpp
Expand Up @@ -7,6 +7,7 @@
//
#include <boost/gil.hpp>
#include <boost/gil/extension/io/png.hpp>
#include <iostream>

using namespace boost::gil;

Expand All @@ -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;
}
Binary file modified example/test_adaptive.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 37 additions & 17 deletions include/boost/gil/image_processing/threshold.hpp
Expand Up @@ -16,10 +16,12 @@
#include <vector>
#include <cmath>

#include <boost/assert.hpp>

#include <boost/gil/image.hpp>
#include <boost/gil/extension/numeric/kernel.hpp>
#include <boost/gil/extension/numeric/convolve.hpp>
#include <boost/assert.hpp>
#include <boost/gil/image_processing/numeric.hpp>

namespace boost { namespace gil {

Expand Down Expand Up @@ -403,31 +405,49 @@ void threshold_adaptive
typedef typename channel_type<SrcView>::type source_channel_t;
typedef typename channel_type<DstView>::type result_channel_t;

image<typename SrcView::value_type> temp_img(src_view.width(), src_view.height());
typename image<typename SrcView::value_type>::view_t temp_view = view(temp_img);
SrcView temp_conv(temp_view);

if (method == threshold_adaptive_method::mean)
{
std::vector<float> mean_kernel_values(kernel_size, 1.0f/kernel_size);
kernel_1d<float> kernel(mean_kernel_values.begin(), kernel_size, kernel_size/2);

image<typename SrcView::value_type> temp_img(src_view.width(), src_view.height());
typename image<typename SrcView::value_type>::view_t temp_view = view(temp_img);
SrcView temp_conv(temp_view);

convolve_1d<pixel<float, typename SrcView::value_type::layout_t>>(
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<float> kernel(
kernel_size,
kernel_size / 2,
kernel_size / 2
);

if (direction == threshold_direction::regular)
{
detail::adaptive_impl<source_channel_t, result_channel_t>(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<source_channel_t, result_channel_t>(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<int, 0>{}); }
);

convolve_2d(src_view, kernel, temp_view);
}

if (direction == threshold_direction::regular)
{
detail::adaptive_impl<source_channel_t, result_channel_t>(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<source_channel_t, result_channel_t>(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; });
}
}

Expand Down

0 comments on commit 5f612cc

Please sign in to comment.