###  | #  |

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
boost::gil::view
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
boost
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
Definition: algorithm.hpp:36