Boost GIL


threshold.hpp
1 //
2 // Copyright 2019 Miral Shah <miralshah2211@gmail.com>
3 //
4 // Use, modification and distribution are subject to the Boost Software License,
5 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 #ifndef BOOST_GIL_IMAGE_PROCESSING_THRESHOLD_HPP
9 #define BOOST_GIL_IMAGE_PROCESSING_THRESHOLD_HPP
10 
11 #include <limits>
12 #include <boost/gil/image.hpp>
13 
14 namespace boost { namespace gil {
15 
16 
17 namespace detail {
18 
19 template
20 <
21  typename SourceChannelT,
22  typename ResultChannelT,
23  typename SrcView,
24  typename DstView,
25  typename Operator
26 >
27 void threshold_impl(SrcView const& src_view, DstView const& dst_view, Operator const& threshold_op)
28 {
29  gil_function_requires<ImageViewConcept<SrcView>>();
30  gil_function_requires<MutableImageViewConcept<DstView>>();
31  gil_function_requires<ColorSpacesCompatibleConcept
32  <
33  typename color_space_type<SrcView>::type,
34  typename color_space_type<DstView>::type>
35  >();
36  static_assert(color_spaces_are_compatible
37  <
38  typename color_space_type<SrcView>::type,
39  typename color_space_type<DstView>::type
40  >::value, "Source and destination views must have pixels with the same color space");
41 
42  //iterate over the image chaecking each pixel value for the threshold
43  for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
44  {
45  typename SrcView::x_iterator src_it = src_view.row_begin(y);
46  typename DstView::x_iterator dst_it = dst_view.row_begin(y);
47 
48  for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
49  {
50  static_transform(src_it[x], dst_it[x], threshold_op);
51  }
52  }
53 }
54 
55 } //namespace boost::gil::detail
56 
57 enum class threshold_direction { regular, inverse };
58 enum class threshold_optimal_value { otsu, triangle };
59 enum class threshold_truncate_mode { threshold, zero };
60 
68 template <typename SrcView, typename DstView>
69 void threshold_binary
70 (
71  SrcView const& src_view,
72  DstView const& dst_view,
73  typename channel_type<DstView>::type threshold_value,
74  typename channel_type<DstView>::type max_value,
75  threshold_direction direction = threshold_direction::regular
76 )
77 {
78  //deciding output channel type and creating functor
79  typedef typename channel_type<SrcView>::type source_channel_t;
80  typedef typename channel_type<DstView>::type result_channel_t;
81 
82  if (direction == threshold_direction::regular)
83  {
84  detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
85  [threshold_value, max_value](source_channel_t px) -> result_channel_t {
86  return px > threshold_value ? max_value : 0;
87  });
88  }
89  else
90  {
91  detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
92  [threshold_value, max_value](source_channel_t px) -> result_channel_t {
93  return px > threshold_value ? 0 : max_value;
94  });
95  }
96 }
97 
105 template <typename SrcView, typename DstView>
106 void threshold_binary
107 (
108  SrcView const& src_view,
109  DstView const& dst_view,
110  typename channel_type<DstView>::type threshold_value,
111  threshold_direction direction = threshold_direction::regular
112 )
113 {
114  typedef typename channel_type<DstView>::type result_channel_t;
115  result_channel_t max_value = std::numeric_limits<result_channel_t>::max();
116  threshold_binary(src_view, dst_view, threshold_value, max_value, direction);
117 }
118 
130 template <typename SrcView, typename DstView>
131 void threshold_truncate
132 (
133  SrcView const& src_view,
134  DstView const& dst_view,
135  typename channel_type<DstView>::type threshold_value,
136  threshold_truncate_mode mode = threshold_truncate_mode::threshold,
137  threshold_direction direction = threshold_direction::regular
138 )
139 {
140  //deciding output channel type and creating functor
141  typedef typename channel_type<SrcView>::type source_channel_t;
142  typedef typename channel_type<DstView>::type result_channel_t;
143 
144  std::function<result_channel_t(source_channel_t)> threshold_logic;
145 
146  if (mode == threshold_truncate_mode::threshold)
147  {
148  if (direction == threshold_direction::regular)
149  {
150  detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
151  [threshold_value](source_channel_t px) -> result_channel_t {
152  return px > threshold_value ? threshold_value : px;
153  });
154  }
155  else
156  {
157  detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
158  [threshold_value](source_channel_t px) -> result_channel_t {
159  return px > threshold_value ? px : threshold_value;
160  });
161  }
162  }
163  else
164  {
165  if (direction == threshold_direction::regular)
166  {
167  detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
168  [threshold_value](source_channel_t px) -> result_channel_t {
169  return px > threshold_value ? px : 0;
170  });
171  }
172  else
173  {
174  detail::threshold_impl<source_channel_t, result_channel_t>(src_view, dst_view,
175  [threshold_value](source_channel_t px) -> result_channel_t {
176  return px > threshold_value ? 0 : px;
177  });
178  }
179  }
180 }
181 
182 }} //namespace boost::gil
183 
184 #endif //BOOST_GIL_IMAGE_PROCESSING_THRESHOLD_HPP
Definition: algorithm.hpp:30