9 #ifndef BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP
10 #define BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP
12 #include <boost/gil/image_processing/kernel.hpp>
13 #include <boost/gil/gray.hpp>
14 #include <boost/gil/image_processing/threshold.hpp>
22 enum class morphological_operation
42 template <
typename SrcView,
typename DstView,
typename Kernel>
43 void morph_impl(SrcView
const& src_view, DstView
const& dst_view, Kernel
const& kernel,
44 morphological_operation identifier)
46 std::ptrdiff_t flip_ker_row, flip_ker_col, row_boundary, col_boundary;
48 for (std::ptrdiff_t view_row = 0; view_row < src_view.height(); ++view_row)
50 for (std::ptrdiff_t view_col = 0; view_col < src_view.width(); ++view_col)
52 target_element = src_view(view_col, view_row);
53 for (std::size_t kernel_row = 0; kernel_row < kernel.size(); ++kernel_row)
55 flip_ker_row = kernel.size() - 1 - kernel_row;
57 for (std::size_t kernel_col = 0; kernel_col < kernel.size(); ++kernel_col)
59 flip_ker_col = kernel.size() - 1 - kernel_col;
63 if (kernel.at(flip_ker_row, flip_ker_col) == 0)
68 row_boundary = view_row + (kernel.center_y() - flip_ker_row);
69 col_boundary = view_col + (kernel.center_x() - flip_ker_col);
72 if (row_boundary >= 0 && row_boundary < src_view.height() &&
73 col_boundary >= 0 && col_boundary < src_view.width())
76 if (identifier == morphological_operation::dilation)
79 (std::max)(src_view(col_boundary, row_boundary)[0], target_element);
81 else if (identifier == morphological_operation::erosion)
84 (std::min)(src_view(col_boundary, row_boundary)[0], target_element);
89 dst_view(view_col, view_row) = target_element;
105 template <
typename SrcView,
typename DstView,
typename Kernel>
106 void morph(SrcView
const& src_view, DstView
const& dst_view, Kernel
const& ker_mat,
107 morphological_operation identifier)
109 BOOST_ASSERT(ker_mat.size() != 0 && src_view.dimensions() == dst_view.dimensions());
110 gil_function_requires<ImageViewConcept<SrcView>>();
111 gil_function_requires<MutableImageViewConcept<DstView>>();
113 gil_function_requires<ColorSpacesCompatibleConcept<typename color_space_type<SrcView>::type,
114 typename color_space_type<DstView>::type>>();
118 for (std::size_t i = 0; i < src_view.num_channels(); i++)
121 ker_mat, identifier);
134 template <
typename SrcView,
typename DiffView>
135 void difference_impl(SrcView
const& src_view1, SrcView
const& src_view2, DiffView
const& diff_view)
137 for (std::ptrdiff_t view_row = 0; view_row < src_view1.height(); ++view_row)
138 for (std::ptrdiff_t view_col = 0; view_col < src_view1.width(); ++view_col)
139 diff_view(view_col, view_row) =
140 src_view1(view_col, view_row) - src_view2(view_col, view_row);
150 template <
typename SrcView,
typename DiffView>
151 void difference(SrcView
const& src_view1, SrcView
const& src_view2, DiffView
const& diff_view)
153 gil_function_requires<ImageViewConcept<SrcView>>();
154 gil_function_requires<MutableImageViewConcept<DiffView>>();
157 typename color_space_type<SrcView>::type,
typename color_space_type<DiffView>::type>>();
159 for (std::size_t i = 0; i < src_view1.num_channels(); i++)
179 template <
typename SrcView,
typename IntOpView,
typename Kernel>
180 void dilate(SrcView
const& src_view, IntOpView
const& int_op_view, Kernel
const& ker_mat,
184 for (
int i = 0; i < iterations; ++i)
185 morph(int_op_view, int_op_view, ker_mat, detail::morphological_operation::dilation);
200 template <
typename SrcView,
typename IntOpView,
typename Kernel>
201 void erode(SrcView
const& src_view, IntOpView
const& int_op_view, Kernel
const& ker_mat,
205 for (
int i = 0; i < iterations; ++i)
206 morph(int_op_view, int_op_view, ker_mat, detail::morphological_operation::erosion);
218 template <
typename SrcView,
typename IntOpView,
typename Kernel>
219 void opening(SrcView
const& src_view, IntOpView
const& int_op_view, Kernel
const& ker_mat)
221 erode(src_view, int_op_view, ker_mat, 1);
222 dilate(int_op_view, int_op_view, ker_mat, 1);
235 template <
typename SrcView,
typename IntOpView,
typename Kernel>
236 void closing(SrcView
const& src_view, IntOpView
const& int_op_view, Kernel
const& ker_mat)
238 dilate(src_view, int_op_view, ker_mat, 1);
239 erode(int_op_view, int_op_view, ker_mat, 1);
253 template <
typename SrcView,
typename DstView,
typename Kernel>
254 void morphological_gradient(SrcView
const& src_view, DstView
const& dst_view, Kernel
const& ker_mat)
256 using namespace boost::gil;
257 gil::image<typename DstView::value_type> int_dilate(src_view.dimensions()),
258 int_erode(src_view.dimensions());
259 dilate(src_view,
view(int_dilate), ker_mat, 1);
260 erode(src_view,
view(int_erode), ker_mat, 1);
273 template <
typename SrcView,
typename DstView,
typename Kernel>
274 void top_hat(SrcView
const& src_view, DstView
const& dst_view, Kernel
const& ker_mat)
276 using namespace boost::gil;
277 gil::image<typename DstView::value_type> int_opening(src_view.dimensions());
278 opening(src_view,
view(int_opening), ker_mat);
291 template <
typename SrcView,
typename DstView,
typename Kernel>
292 void black_hat(SrcView
const& src_view, DstView
const& dst_view, Kernel
const& ker_mat)
294 using namespace boost::gil;
295 gil::image<typename DstView::value_type> int_closing(src_view.dimensions());
296 closing(src_view,
view(int_closing), ker_mat);
301 #endif // BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP