|
|
|||
File indexing completed on 2025-12-16 09:51:52
0001 // 0002 // Copyright 2021 Prathamesh Tagore <prathameshtagore@gmail.com> 0003 // 0004 // Use, modification and distribution are subject to the Boost Software License, 0005 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 0006 // http://www.boost.org/LICENSE_1_0.txt) 0007 // 0008 0009 #ifndef BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP 0010 #define BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP 0011 0012 #include <boost/gil/image_processing/kernel.hpp> 0013 #include <boost/gil/gray.hpp> 0014 #include <boost/gil/image_processing/threshold.hpp> 0015 0016 namespace boost { namespace gil { namespace detail { 0017 0018 enum class morphological_operation 0019 { 0020 dilation, 0021 erosion, 0022 }; 0023 0024 /// \addtogroup ImageProcessing 0025 /// @{ 0026 0027 /// \brief Implements morphological operations at pixel level.This function 0028 /// compares neighbouring pixel values according to the kernel and choose 0029 /// minimum/mamximum neighbouring pixel value and assigns it to the pixel under 0030 /// consideration. 0031 /// \param src_view - Source/Input image view. 0032 /// \param dst_view - View which stores the final result of operations performed by this function. 0033 /// \param kernel - Kernel matrix/structuring element containing 0's and 1's 0034 /// which will be used for applying the required morphological operation. 0035 /// \param identifier - Indicates the type of morphological operation to be applied. 0036 /// \tparam SrcView type of source image. 0037 /// \tparam DstView type of output image. 0038 /// \tparam Kernel type of structuring element. 0039 template <typename SrcView, typename DstView, typename Kernel> 0040 void morph_impl(SrcView const& src_view, DstView const& dst_view, Kernel const& kernel, 0041 morphological_operation identifier) 0042 { 0043 std::ptrdiff_t flip_ker_row, flip_ker_col, row_boundary, col_boundary; 0044 typename channel_type<typename SrcView::value_type>::type target_element; 0045 for (std::ptrdiff_t view_row = 0; view_row < src_view.height(); ++view_row) 0046 { 0047 for (std::ptrdiff_t view_col = 0; view_col < src_view.width(); ++view_col) 0048 { 0049 target_element = src_view(view_col, view_row); 0050 for (std::size_t kernel_row = 0; kernel_row < kernel.size(); ++kernel_row) 0051 { 0052 flip_ker_row = kernel.size() - 1 - kernel_row; // row index of flipped kernel 0053 0054 for (std::size_t kernel_col = 0; kernel_col < kernel.size(); ++kernel_col) 0055 { 0056 flip_ker_col = kernel.size() - 1 - kernel_col; // column index of flipped kernel 0057 0058 // We ensure that we consider only those pixels which are overlapped 0059 // on a non-zero kernel_element as 0060 if (kernel.at(flip_ker_row, flip_ker_col) == 0) 0061 { 0062 continue; 0063 } 0064 // index of input signal, used for checking boundary 0065 row_boundary = view_row + (kernel.center_y() - flip_ker_row); 0066 col_boundary = view_col + (kernel.center_x() - flip_ker_col); 0067 0068 // ignore input samples which are out of bound 0069 if (row_boundary >= 0 && row_boundary < src_view.height() && 0070 col_boundary >= 0 && col_boundary < src_view.width()) 0071 { 0072 0073 if (identifier == morphological_operation::dilation) 0074 { 0075 target_element = 0076 (std::max)(src_view(col_boundary, row_boundary)[0], target_element); 0077 } 0078 else if (identifier == morphological_operation::erosion) 0079 { 0080 target_element = 0081 (std::min)(src_view(col_boundary, row_boundary)[0], target_element); 0082 } 0083 } 0084 } 0085 } 0086 dst_view(view_col, view_row) = target_element; 0087 } 0088 } 0089 } 0090 0091 /// \brief Checks feasibility of the desired operation and passes parameter 0092 /// values to the function morph_impl alongwith individual channel views of the 0093 /// input image. 0094 /// \param src_view - Source/Input image view. 0095 /// \param dst_view - View which stores the final result of operations performed by this function. 0096 /// \param kernel - Kernel matrix/structuring element containing 0's and 1's 0097 /// which will be used for applying the required morphological operation. 0098 /// \param identifier - Indicates the type of morphological operation to be applied. 0099 /// \tparam SrcView type of source image. 0100 /// \tparam DstView type of output image. 0101 /// \tparam Kernel type of structuring element. 0102 template <typename SrcView, typename DstView, typename Kernel> 0103 void morph(SrcView const& src_view, DstView const& dst_view, Kernel const& ker_mat, 0104 morphological_operation identifier) 0105 { 0106 BOOST_ASSERT(ker_mat.size() != 0 && src_view.dimensions() == dst_view.dimensions()); 0107 gil_function_requires<ImageViewConcept<SrcView>>(); 0108 gil_function_requires<MutableImageViewConcept<DstView>>(); 0109 0110 gil_function_requires<ColorSpacesCompatibleConcept<typename color_space_type<SrcView>::type, 0111 typename color_space_type<DstView>::type>>(); 0112 0113 gil::image<typename DstView::value_type> intermediate_img(src_view.dimensions()); 0114 0115 for (std::size_t i = 0; i < src_view.num_channels(); i++) 0116 { 0117 morph_impl(nth_channel_view(src_view, i), nth_channel_view(view(intermediate_img), i), 0118 ker_mat, identifier); 0119 } 0120 copy_pixels(view(intermediate_img), dst_view); 0121 } 0122 0123 /// \brief Calculates the difference between pixel values of first image_view 0124 /// and second image_view. 0125 /// \param src_view1 - First parameter for subtraction of views. 0126 /// \param src_view2 - Second parameter for subtraction of views. 0127 /// \param diff_view - View containing result of the subtraction of second view from 0128 /// the first view. 0129 /// \tparam SrcView type of source/Input images used for subtraction. 0130 /// \tparam DiffView type of image view containing the result of subtraction. 0131 template <typename SrcView, typename DiffView> 0132 void difference_impl(SrcView const& src_view1, SrcView const& src_view2, DiffView const& diff_view) 0133 { 0134 for (std::ptrdiff_t view_row = 0; view_row < src_view1.height(); ++view_row) 0135 for (std::ptrdiff_t view_col = 0; view_col < src_view1.width(); ++view_col) 0136 diff_view(view_col, view_row) = 0137 src_view1(view_col, view_row) - src_view2(view_col, view_row); 0138 } 0139 0140 /// \brief Passes parameter values to the function 'difference_impl' alongwith 0141 /// individual channel views of input images. 0142 /// \param src_view1 - First parameter for subtraction of views. 0143 /// \param src_view2 - Second parameter for subtraction of views. 0144 /// \param diff_view - View containing result of the subtraction of second view from the first view. 0145 /// \tparam SrcView type of source/Input images used for subtraction. 0146 /// \tparam DiffView type of image view containing the result of subtraction. 0147 template <typename SrcView, typename DiffView> 0148 void difference(SrcView const& src_view1, SrcView const& src_view2, DiffView const& diff_view) 0149 { 0150 gil_function_requires<ImageViewConcept<SrcView>>(); 0151 gil_function_requires<MutableImageViewConcept<DiffView>>(); 0152 0153 gil_function_requires<ColorSpacesCompatibleConcept< 0154 typename color_space_type<SrcView>::type, typename color_space_type<DiffView>::type>>(); 0155 0156 for (std::size_t i = 0; i < src_view1.num_channels(); i++) 0157 { 0158 difference_impl(nth_channel_view(src_view1, i), nth_channel_view(src_view2, i), 0159 nth_channel_view(diff_view, i)); 0160 } 0161 } 0162 } // namespace detail 0163 0164 /// \brief Applies morphological dilation on the input image view using given 0165 /// structuring element. It gives the maximum overlapped value to the pixel 0166 /// overlapping with the center element of structuring element. \param src_view 0167 /// - Source/input image view. 0168 /// \param int_op_view - view for writing output and performing intermediate operations. 0169 /// \param ker_mat - Kernel matrix/structuring element containing 0's and 1's which will be used for 0170 /// applying dilation. 0171 /// \param iterations - Specifies the number of times dilation is to be applied on the input image 0172 /// view. 0173 /// \tparam SrcView type of source image, models gil::ImageViewConcept. 0174 /// \tparam IntOpView type of output image, models gil::MutableImageViewConcept. 0175 /// \tparam Kernel type of structuring element. 0176 template <typename SrcView, typename IntOpView, typename Kernel> 0177 void dilate(SrcView const& src_view, IntOpView const& int_op_view, Kernel const& ker_mat, 0178 int iterations) 0179 { 0180 copy_pixels(src_view, int_op_view); 0181 for (int i = 0; i < iterations; ++i) 0182 morph(int_op_view, int_op_view, ker_mat, detail::morphological_operation::dilation); 0183 } 0184 0185 /// \brief Applies morphological erosion on the input image view using given 0186 /// structuring element. It gives the minimum overlapped value to the pixel 0187 /// overlapping with the center element of structuring element. 0188 /// \param src_view - Source/input image view. 0189 /// \param int_op_view - view for writing output and performing intermediate operations. 0190 /// \param ker_mat - Kernel matrix/structuring element containing 0's and 1's which will be used for 0191 /// applying erosion. 0192 /// \param iterations - Specifies the number of times erosion is to be applied on the input 0193 /// image view. 0194 /// \tparam SrcView type of source image, models gil::ImageViewConcept. 0195 /// \tparam IntOpView type of output image, models gil::MutableImageViewConcept. 0196 /// \tparam Kernel type of structuring element. 0197 template <typename SrcView, typename IntOpView, typename Kernel> 0198 void erode(SrcView const& src_view, IntOpView const& int_op_view, Kernel const& ker_mat, 0199 int iterations) 0200 { 0201 copy_pixels(src_view, int_op_view); 0202 for (int i = 0; i < iterations; ++i) 0203 morph(int_op_view, int_op_view, ker_mat, detail::morphological_operation::erosion); 0204 } 0205 0206 /// \brief Performs erosion and then dilation on the input image view . This 0207 /// operation is utilized for removing noise from images. 0208 /// \param src_view - Source/input image view. 0209 /// \param int_op_view - view for writing output and performing intermediate operations. 0210 /// \param ker_mat - Kernel matrix/structuring element containing 0's and 1's which will be used for 0211 /// applying the opening operation. 0212 /// \tparam SrcView type of source image, models gil::ImageViewConcept. 0213 /// \tparam IntOpView type of output image, models gil::MutableImageViewConcept. 0214 /// \tparam Kernel type of structuring element. 0215 template <typename SrcView, typename IntOpView, typename Kernel> 0216 void opening(SrcView const& src_view, IntOpView const& int_op_view, Kernel const& ker_mat) 0217 { 0218 erode(src_view, int_op_view, ker_mat, 1); 0219 dilate(int_op_view, int_op_view, ker_mat, 1); 0220 } 0221 0222 /// \brief Performs dilation and then erosion on the input image view which is 0223 /// exactly opposite to the opening operation . Closing operation can be 0224 /// utilized for closing small holes inside foreground objects. 0225 /// \param src_view - Source/input image view. 0226 /// \param int_op_view - view for writing output and performing intermediate operations. 0227 /// \param ker_mat - Kernel matrix/structuring element containing 0's and 1's which will be used for 0228 /// applying the closing operation. 0229 /// \tparam SrcView type of source image, models gil::ImageViewConcept. 0230 /// \tparam IntOpView type of output image, models gil::MutableImageViewConcept. 0231 /// \tparam Kernel type of structuring element. 0232 template <typename SrcView, typename IntOpView, typename Kernel> 0233 void closing(SrcView const& src_view, IntOpView const& int_op_view, Kernel const& ker_mat) 0234 { 0235 dilate(src_view, int_op_view, ker_mat, 1); 0236 erode(int_op_view, int_op_view, ker_mat, 1); 0237 } 0238 0239 /// \brief Calculates the difference between image views generated after 0240 /// applying dilation dilation and erosion on an image . The resultant image 0241 /// will look like the outline of the object(s) present in the image. 0242 /// \param src_view - Source/input image view. 0243 /// \param dst_view - Destination view which will store the final result of morphological 0244 /// gradient operation. 0245 /// \param ker_mat - Kernel matrix/structuring element containing 0's and 1's which 0246 /// will be used for applying the morphological gradient operation. 0247 /// \tparam SrcView type of source image, models gil::ImageViewConcept. 0248 /// \tparam DstView type of output image, models gil::MutableImageViewConcept. 0249 /// \tparam Kernel type of structuring element. 0250 template <typename SrcView, typename DstView, typename Kernel> 0251 void morphological_gradient(SrcView const& src_view, DstView const& dst_view, Kernel const& ker_mat) 0252 { 0253 using namespace boost::gil; 0254 gil::image<typename DstView::value_type> int_dilate(src_view.dimensions()), 0255 int_erode(src_view.dimensions()); 0256 dilate(src_view, view(int_dilate), ker_mat, 1); 0257 erode(src_view, view(int_erode), ker_mat, 1); 0258 difference(view(int_dilate), view(int_erode), dst_view); 0259 } 0260 0261 /// \brief Calculates the difference between input image view and the view 0262 /// generated by opening operation on the input image view. 0263 /// \param src_view - Source/input image view. 0264 /// \param dst_view - Destination view which will store the final result of top hat operation. 0265 /// \param ker_mat - Kernel matrix/structuring element containing 0's and 1's which will be used for 0266 /// applying the top hat operation. 0267 /// \tparam SrcView type of source image, models gil::ImageViewConcept. 0268 /// \tparam DstView type of output image, models gil::MutableImageViewConcept. 0269 /// \tparam Kernel type of structuring element. 0270 template <typename SrcView, typename DstView, typename Kernel> 0271 void top_hat(SrcView const& src_view, DstView const& dst_view, Kernel const& ker_mat) 0272 { 0273 using namespace boost::gil; 0274 gil::image<typename DstView::value_type> int_opening(src_view.dimensions()); 0275 opening(src_view, view(int_opening), ker_mat); 0276 difference(src_view, view(int_opening), dst_view); 0277 } 0278 0279 /// \brief Calculates the difference between closing of the input image and 0280 /// input image. 0281 /// \param src_view - Source/input image view. 0282 /// \param dst_view - Destination view which will store the final result of black hat operation. 0283 /// \param ker_mat - Kernel matrix/structuring element containing 0's and 1's 0284 /// which will be used for applying the black hat operation. 0285 /// \tparam SrcView type of source image, models gil::ImageViewConcept. 0286 /// \tparam DstView type of output image, models gil::MutableImageViewConcept. 0287 /// \tparam Kernel type of structuring element. 0288 template <typename SrcView, typename DstView, typename Kernel> 0289 void black_hat(SrcView const& src_view, DstView const& dst_view, Kernel const& ker_mat) 0290 { 0291 using namespace boost::gil; 0292 gil::image<typename DstView::value_type> int_closing(src_view.dimensions()); 0293 closing(src_view, view(int_closing), ker_mat); 0294 difference(view(int_closing), src_view, dst_view); 0295 } 0296 /// @} 0297 }} // namespace boost::gil 0298 #endif // BOOST_GIL_IMAGE_PROCESSING_MORPHOLOGY_HPP
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|