8 #ifndef BOOST_GIL_IMAGE_PROCESSING_THRESHOLD_HPP 9 #define BOOST_GIL_IMAGE_PROCESSING_THRESHOLD_HPP 13 #include <type_traits> 19 #include <boost/gil/image.hpp> 20 #include <boost/gil/extension/numeric/kernel.hpp> 21 #include <boost/gil/extension/numeric/convolve.hpp> 22 #include <boost/assert.hpp> 24 namespace boost {
namespace gil {
30 typename SourceChannelT,
31 typename ResultChannelT,
36 void threshold_impl(SrcView
const& src_view, DstView
const& dst_view, Operator
const& threshold_op)
38 gil_function_requires<ImageViewConcept<SrcView>>();
39 gil_function_requires<MutableImageViewConcept<DstView>>();
40 static_assert(color_spaces_are_compatible
42 typename color_space_type<SrcView>::type,
43 typename color_space_type<DstView>::type
44 >::value,
"Source and destination views must have pixels with the same color space");
47 for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
49 typename SrcView::x_iterator src_it = src_view.row_begin(y);
50 typename DstView::x_iterator dst_it = dst_view.row_begin(y);
52 for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
54 static_transform(src_it[x], dst_it[x], threshold_op);
89 enum class threshold_adaptive_method
106 template <
typename SrcView,
typename DstView>
108 SrcView
const& src_view,
109 DstView
const& dst_view,
121 detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
122 [threshold_value, max_value](source_channel_t px) -> result_channel_t {
123 return px > threshold_value ? max_value : 0;
128 detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
129 [threshold_value, max_value](source_channel_t px) -> result_channel_t {
130 return px > threshold_value ? 0 : max_value;
145 template <
typename SrcView,
typename DstView>
147 SrcView
const& src_view,
148 DstView
const& dst_view,
156 result_channel_t max_value = std::numeric_limits<result_channel_t>::max();
157 threshold_binary(src_view, dst_view, threshold_value, max_value, direction);
171 template <
typename SrcView,
typename DstView>
173 SrcView
const& src_view,
174 DstView
const& dst_view,
184 std::function<result_channel_t(source_channel_t)> threshold_logic;
190 detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
191 [threshold_value](source_channel_t px) -> result_channel_t {
192 return px > threshold_value ? threshold_value : px;
197 detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
198 [threshold_value](source_channel_t px) -> result_channel_t {
199 return px > threshold_value ? px : threshold_value;
207 detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
208 [threshold_value](source_channel_t px) -> result_channel_t {
209 return px > threshold_value ? px : 0;
214 detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
215 [threshold_value](source_channel_t px) -> result_channel_t {
216 return px > threshold_value ? 0 : px;
224 template <
typename SrcView,
typename DstView>
225 void otsu_impl(SrcView
const& src_view, DstView
const& dst_view,
threshold_direction direction)
230 std::array<std::size_t, 256> histogram{};
233 auto min = std::numeric_limits<source_channel_t>::max(),
234 max = std::numeric_limits<source_channel_t>::min();
236 if (
sizeof(source_channel_t) > 1 || std::is_signed<source_channel_t>::value)
239 for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
241 typename SrcView::x_iterator src_it = src_view.row_begin(y);
242 for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
244 if (src_it[x] < min) min = src_it[x];
245 if (src_it[x] > min) min = src_it[x];
250 for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
252 typename SrcView::x_iterator src_it = src_view.row_begin(y);
254 for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
256 histogram[((src_it[x] - min) * 255) / (max - min)]++;
263 for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
265 typename SrcView::x_iterator src_it = src_view.row_begin(y);
267 for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
269 histogram[src_it[x]]++;
285 std::ptrdiff_t total_pixel = src_view.height() * src_view.width();
286 std::ptrdiff_t sum_total = 0, sum_back = 0;
287 std::size_t weight_back = 0, weight_fore = 0,
threshold = 0;
288 double var_max = 0, mean_back, mean_fore, var_intra_class;
290 for (std::size_t t = 0; t < 256; t++)
292 sum_total += t * histogram[t];
295 for (
int t = 0; t < 256; t++)
297 weight_back += histogram[t];
298 if (weight_back == 0)
continue;
300 weight_fore = total_pixel - weight_back;
301 if (weight_fore == 0)
break;
303 sum_back += t * histogram[t];
305 mean_back = sum_back / weight_back;
306 mean_fore = (sum_total - sum_back) / weight_fore;
309 var_intra_class = weight_back * weight_fore * (mean_back - mean_fore) * (mean_back - mean_fore);
312 if (var_intra_class > var_max) {
313 var_max = var_intra_class;
317 if (
sizeof(source_channel_t) > 1 && std::is_unsigned<source_channel_t>::value)
327 template <
typename SrcView,
typename DstView>
328 void threshold_optimal
330 SrcView
const& src_view,
331 DstView
const& dst_view,
338 for (std::size_t i = 0; i < src_view.num_channels(); i++)
341 (nth_channel_view(src_view, i), nth_channel_view(dst_view, i), direction);
350 typename SourceChannelT,
351 typename ResultChannelT,
358 SrcView
const& src_view,
359 SrcView
const& convolved_view,
360 DstView
const& dst_view,
361 Operator
const& threshold_op
365 gil_function_requires<ImageViewConcept<SrcView>>();
366 gil_function_requires<MutableImageViewConcept<DstView>>();
368 static_assert(color_spaces_are_compatible
370 typename color_space_type<SrcView>::type,
371 typename color_space_type<DstView>::type
372 >::value,
"Source and destination views must have pixels with the same color space");
375 for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
377 typename SrcView::x_iterator src_it = src_view.row_begin(y);
378 typename SrcView::x_iterator convolved_it = convolved_view.row_begin(y);
379 typename DstView::x_iterator dst_it = dst_view.row_begin(y);
381 for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
383 static_transform(src_it[x], convolved_it[x], dst_it[x], threshold_op);
389 template <
typename SrcView,
typename DstView>
390 void threshold_adaptive
392 SrcView
const& src_view,
393 DstView
const& dst_view,
395 std::size_t kernel_size,
396 threshold_adaptive_method method = threshold_adaptive_method::mean,
401 BOOST_ASSERT_MSG((kernel_size % 2 != 0),
"Kernel size must be an odd number");
406 if (method == threshold_adaptive_method::mean)
408 std::vector<float> mean_kernel_values(kernel_size, 1.0f/kernel_size);
409 kernel_1d<float> kernel(mean_kernel_values.begin(), kernel_size, kernel_size/2);
412 typename image<typename SrcView::value_type>::view_t temp_view =
view(temp_img);
413 SrcView temp_conv(temp_view);
415 convolve<pixel<float, typename SrcView::value_type::layout_t>>(
416 src_view, kernel, temp_view
421 detail::adaptive_impl<source_channel_t, result_channel_t>(src_view, temp_conv, dst_view,
422 [max_value, constant](source_channel_t px, source_channel_t
threshold) -> result_channel_t
423 {
return px > (
threshold - constant) ? max_value : 0; });
427 detail::adaptive_impl<source_channel_t, result_channel_t>(src_view, temp_conv, dst_view,
428 [max_value, constant](source_channel_t px, source_channel_t
threshold) -> result_channel_t
429 {
return px > (
threshold - constant) ? 0 : max_value; });
434 template <
typename SrcView,
typename DstView>
435 void threshold_adaptive
437 SrcView
const& src_view,
438 DstView
const& dst_view,
439 std::size_t kernel_size,
440 threshold_adaptive_method method = threshold_adaptive_method::mean,
448 result_channel_t max_value = std::numeric_limits<result_channel_t>::max();
450 threshold_adaptive(src_view, dst_view, max_value, kernel_size, method, direction, constant);
457 #endif //BOOST_GIL_IMAGE_PROCESSING_THRESHOLD_HPP Definition: algorithm.hpp:30
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:146
threshold_truncate_mode
TODO.
Definition: threshold.hpp:83
threshold_direction
Definition: threshold.hpp:67
threshold_optimal_value
Method of optimal threshold value calculation.
Definition: threshold.hpp:75
Consider values less than or equal to threshold value.
container interface over image view. Models ImageConcept, PixelBasedConcept
Definition: image.hpp:40
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:172
Consider values greater than threshold value.