Boost GIL


filter.hpp
1 //
2 // Copyright 2019 Miral Shah <miralshah2211@gmail.com>
3 // Copyright 2021 Pranam Lashkari <plashkari628@gmail.com>
4 //
5 // Use, modification and distribution are subject to the Boost Software License,
6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9 
10 #ifndef BOOST_GIL_IMAGE_PROCESSING_FILTER_HPP
11 #define BOOST_GIL_IMAGE_PROCESSING_FILTER_HPP
12 
13 #include <boost/gil/image_processing/kernel.hpp>
14 
15 #include <boost/gil/image_processing/convolve.hpp>
16 
17 #include <boost/gil/image.hpp>
18 #include <boost/gil/image_view.hpp>
19 #include <boost/gil/algorithm.hpp>
20 
21 #include <cstddef>
22 #include <vector>
23 
24 namespace boost { namespace gil {
25 
26 template <typename SrcView, typename DstView>
27 void box_filter(
28  SrcView const& src_view,
29  DstView const& dst_view,
30  std::size_t kernel_size,
31  long int anchor = -1,
32  bool normalize=true,
33  boundary_option option = boundary_option::extend_zero
34 )
35 {
36  gil_function_requires<ImageViewConcept<SrcView>>();
37  gil_function_requires<MutableImageViewConcept<DstView>>();
38  static_assert(color_spaces_are_compatible
39  <
40  typename color_space_type<SrcView>::type,
41  typename color_space_type<DstView>::type
42  >::value, "Source and destination views must have pixels with the same color space");
43 
44  std::vector<float> kernel_values;
45  if (normalize) { kernel_values.resize(kernel_size, 1.0f / float(kernel_size)); }
46  else { kernel_values.resize(kernel_size, 1.0f); }
47 
48  if (anchor == -1) anchor = static_cast<int>(kernel_size / 2);
49  kernel_1d<float> kernel(kernel_values.begin(), kernel_size, anchor);
50 
51  detail::convolve_1d
52  <
53  pixel<float, typename SrcView::value_type::layout_t>
54  >(src_view, kernel, dst_view, option);
55 }
56 
57 template <typename SrcView, typename DstView>
58 void blur(
59  SrcView const& src_view,
60  DstView const& dst_view,
61  std::size_t kernel_size,
62  long int anchor = -1,
63  boundary_option option = boundary_option::extend_zero
64 )
65 {
66  box_filter(src_view, dst_view, kernel_size, anchor, true, option);
67 }
68 
69 
70 namespace detail
71 {
72 template <typename SrcView, typename DstView>
73 void filter_median_impl(SrcView const& src_view, DstView const& dst_view, std::size_t kernel_size)
74 {
75  std::size_t half_kernel_size = kernel_size / 2;
76 
77  // deciding output channel type and creating functor
78  using src_channel_t = typename channel_type<SrcView>::type;
79 
80  std::vector<src_channel_t> values;
81  values.reserve(kernel_size * kernel_size);
82 
83  for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
84  {
85  typename DstView::x_iterator dst_it = dst_view.row_begin(y);
86 
87  for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
88  {
89  auto sub_view = subimage_view(
90  src_view,
91  x - half_kernel_size, y - half_kernel_size,
92  kernel_size,
93  kernel_size
94  );
95  values.assign(sub_view.begin(), sub_view.end());
96 
97  std::nth_element(values.begin(), values.begin() + (values.size() / 2), values.end());
98  dst_it[x] = values[values.size() / 2];
99  }
100  }
101 }
102 } // namespace detail
103 
104 template <typename SrcView, typename DstView>
105 void median_filter(SrcView const& src_view, DstView const& dst_view, std::size_t kernel_size)
106 {
107  static_assert(color_spaces_are_compatible
108  <
109  typename color_space_type<SrcView>::type,
110  typename color_space_type<DstView>::type
111  >::value, "Source and destination views must have pixels with the same color space");
112 
113  std::size_t half_kernel_size = kernel_size / 2;
114  auto extended_img = extend_boundary(
115  src_view,
116  half_kernel_size,
117  boundary_option::extend_constant
118  );
119  auto extended_view = subimage_view(
120  view(extended_img),
121  half_kernel_size,
122  half_kernel_size,
123  src_view.width(),
124  src_view.height()
125  );
126 
127  for (std::size_t channel = 0; channel < extended_view.num_channels(); channel++)
128  {
129  detail::filter_median_impl(
130  nth_channel_view(extended_view, channel),
131  nth_channel_view(dst_view, channel),
132  kernel_size
133  );
134  }
135 }
136 
137 }} //namespace boost::gil
138 
139 #endif // !BOOST_GIL_IMAGE_PROCESSING_FILTER_HPP
auto view(image< Pixel, IsPlanar, Alloc > &img) -> typename image< Pixel, IsPlanar, Alloc >::view_t const &
Returns the non-constant-pixel view of an image.
Definition: image.hpp:565
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
Definition: algorithm.hpp:36