123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- //
- // Copyright 2019 Miral Shah <miralshah2211@gmail.com>
- //
- // Use, modification and distribution are subject to the Boost Software License,
- // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef BOOST_GIL_IMAGE_PROCESSING_FILTER_HPP
- #define BOOST_GIL_IMAGE_PROCESSING_FILTER_HPP
- #include <boost/gil/extension/numeric/algorithm.hpp>
- #include <boost/gil/extension/numeric/kernel.hpp>
- #include <boost/gil/extension/numeric/convolve.hpp>
- #include <boost/gil/image.hpp>
- #include <boost/gil/image_view.hpp>
- #include <cstddef>
- #include <vector>
- namespace boost { namespace gil {
- template <typename SrcView, typename DstView>
- void box_filter(
- SrcView const& src_view,
- DstView const& dst_view,
- std::size_t kernel_size,
- long int anchor = -1,
- bool normalize=true,
- boundary_option option = boundary_option::extend_zero
- )
- {
- gil_function_requires<ImageViewConcept<SrcView>>();
- gil_function_requires<MutableImageViewConcept<DstView>>();
- static_assert(color_spaces_are_compatible
- <
- typename color_space_type<SrcView>::type,
- typename color_space_type<DstView>::type
- >::value, "Source and destination views must have pixels with the same color space");
- std::vector<float> kernel_values;
- if (normalize) { kernel_values.resize(kernel_size, 1.0f / float(kernel_size)); }
- else { kernel_values.resize(kernel_size, 1.0f); }
- if (anchor == -1) anchor = static_cast<int>(kernel_size / 2);
- kernel_1d<float> kernel(kernel_values.begin(), kernel_size, anchor);
- detail::convolve_1d
- <
- pixel<float, typename SrcView::value_type::layout_t>
- >(src_view, kernel, dst_view, option);
- }
- template <typename SrcView, typename DstView>
- void blur(
- SrcView const& src_view,
- DstView const& dst_view,
- std::size_t kernel_size,
- long int anchor = -1,
- boundary_option option = boundary_option::extend_zero
- )
- {
- box_filter(src_view, dst_view, kernel_size, anchor, true, option);
- }
- namespace detail
- {
- template <typename SrcView, typename DstView>
- void filter_median_impl(SrcView const& src_view, DstView const& dst_view, std::size_t kernel_size)
- {
- std::size_t half_kernel_size = kernel_size / 2;
- // deciding output channel type and creating functor
- using src_channel_t = typename channel_type<SrcView>::type;
- std::vector<src_channel_t> values;
- values.reserve(kernel_size * kernel_size);
- for (std::ptrdiff_t y = 0; y < src_view.height(); y++)
- {
- typename DstView::x_iterator dst_it = dst_view.row_begin(y);
- for (std::ptrdiff_t x = 0; x < src_view.width(); x++)
- {
- auto sub_view = subimage_view(
- src_view,
- x - half_kernel_size, y - half_kernel_size,
- kernel_size,
- kernel_size
- );
- values.assign(sub_view.begin(), sub_view.end());
- std::nth_element(values.begin(), values.begin() + (values.size() / 2), values.end());
- dst_it[x] = values[values.size() / 2];
- }
- }
- }
- } // namespace detail
- template <typename SrcView, typename DstView>
- void median_filter(SrcView const& src_view, DstView const& dst_view, std::size_t kernel_size)
- {
- static_assert(color_spaces_are_compatible
- <
- typename color_space_type<SrcView>::type,
- typename color_space_type<DstView>::type
- >::value, "Source and destination views must have pixels with the same color space");
- std::size_t half_kernel_size = kernel_size / 2;
- auto extended_img = extend_boundary(
- src_view,
- half_kernel_size,
- boundary_option::extend_constant
- );
- auto extended_view = subimage_view(
- view(extended_img),
- half_kernel_size,
- half_kernel_size,
- src_view.width(),
- src_view.height()
- );
- for (std::size_t channel = 0; channel < extended_view.num_channels(); channel++)
- {
- detail::filter_median_impl(
- nth_channel_view(extended_view, channel),
- nth_channel_view(dst_view, channel),
- kernel_size
- );
- }
- }
- }} //namespace boost::gil
- #endif // !BOOST_GIL_IMAGE_PROCESSING_FILTER_HPP
|