| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- //
- // Copyright 2005-2007 Adobe Systems Incorporated
- //
- // Distributed under 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_EXTENSION_NUMERIC_ALGORITHM_HPP
- #define BOOST_GIL_EXTENSION_NUMERIC_ALGORITHM_HPP
- #include <boost/gil/extension/numeric/pixel_numeric_operations.hpp>
- #include <boost/gil/metafunctions.hpp>
- #include <boost/gil/pixel_iterator.hpp>
- #include <boost/assert.hpp>
- #include <algorithm>
- #include <iterator>
- #include <numeric>
- namespace boost { namespace gil {
- /// \brief Returns the reference proxy associated with a type that has a \p "reference" member type alias.
- ///
- /// The reference proxy is the reference type, but with stripped-out C++ reference. It models PixelConcept
- template <typename T>
- struct pixel_proxy : public remove_reference<typename T::reference> {};
- /// \brief std::for_each for a pair of iterators
- template <typename Iterator1,typename Iterator2,typename BinaryFunction>
- BinaryFunction for_each(Iterator1 first1,Iterator1 last1,Iterator2 first2,BinaryFunction f) {
- while(first1!=last1)
- f(*first1++,*first2++);
- return f;
- }
- template <typename SrcIterator,typename DstIterator>
- inline DstIterator assign_pixels(SrcIterator src,SrcIterator src_end,DstIterator dst) {
- for_each(src,src_end,dst,pixel_assigns_t<typename pixel_proxy<typename std::iterator_traits<SrcIterator>::value_type>::type,
- typename pixel_proxy<typename std::iterator_traits<DstIterator>::value_type>::type>());
- return dst+(src_end-src);
- }
- namespace detail {
- template <std::size_t Size>
- struct inner_product_k_t {
- template <class _InputIterator1, class _InputIterator2, class _Tp,
- class _BinaryOperation1, class _BinaryOperation2>
- static _Tp apply(_InputIterator1 __first1,
- _InputIterator2 __first2, _Tp __init,
- _BinaryOperation1 __binary_op1,
- _BinaryOperation2 __binary_op2) {
- __init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
- return inner_product_k_t<Size-1>::template apply(__first1+1,__first2+1,__init,
- __binary_op1, __binary_op2);
- }
- };
- template <>
- struct inner_product_k_t<0> {
- template <class _InputIterator1, class _InputIterator2, class _Tp,
- class _BinaryOperation1, class _BinaryOperation2>
- static _Tp apply(_InputIterator1 __first1,
- _InputIterator2 __first2, _Tp __init,
- _BinaryOperation1 __binary_op1,
- _BinaryOperation2 __binary_op2) {
- return __init;
- }
- };
- } // namespace detail
- /// static version of std::inner_product
- template <std::size_t Size,
- class _InputIterator1, class _InputIterator2, class _Tp,
- class _BinaryOperation1, class _BinaryOperation2>
- BOOST_FORCEINLINE
- _Tp inner_product_k(_InputIterator1 __first1,
- _InputIterator2 __first2,
- _Tp __init,
- _BinaryOperation1 __binary_op1,
- _BinaryOperation2 __binary_op2) {
- return detail::inner_product_k_t<Size>::template apply(__first1,__first2,__init,
- __binary_op1, __binary_op2);
- }
- /// \brief 1D un-guarded correlation with a variable-size kernel
- template <typename PixelAccum,typename SrcIterator,typename KernelIterator,typename Integer,typename DstIterator>
- inline DstIterator correlate_pixels_n(SrcIterator src_begin,SrcIterator src_end,
- KernelIterator ker_begin,Integer ker_size,
- DstIterator dst_begin) {
- using PIXEL_SRC_REF = typename pixel_proxy<typename std::iterator_traits<SrcIterator>::value_type>::type;
- using PIXEL_DST_REF = typename pixel_proxy<typename std::iterator_traits<DstIterator>::value_type>::type;
- using kernel_type = typename std::iterator_traits<KernelIterator>::value_type;
- PixelAccum acc_zero; pixel_zeros_t<PixelAccum>()(acc_zero);
- while(src_begin!=src_end) {
- pixel_assigns_t<PixelAccum,PIXEL_DST_REF>()(
- std::inner_product(src_begin,src_begin+ker_size,ker_begin,acc_zero,
- pixel_plus_t<PixelAccum,PixelAccum,PixelAccum>(),
- pixel_multiplies_scalar_t<PIXEL_SRC_REF,kernel_type,PixelAccum>()),
- *dst_begin);
- ++src_begin; ++dst_begin;
- }
- return dst_begin;
- }
- /// \brief 1D un-guarded correlation with a fixed-size kernel
- template <std::size_t Size,typename PixelAccum,typename SrcIterator,typename KernelIterator,typename DstIterator>
- inline DstIterator correlate_pixels_k(SrcIterator src_begin,SrcIterator src_end,
- KernelIterator ker_begin,
- DstIterator dst_begin) {
- using PIXEL_SRC_REF = typename pixel_proxy<typename std::iterator_traits<SrcIterator>::value_type>::type;
- using PIXEL_DST_REF = typename pixel_proxy<typename std::iterator_traits<DstIterator>::value_type>::type;
- using kernel_type = typename std::iterator_traits<KernelIterator>::value_type;
- PixelAccum acc_zero; pixel_zeros_t<PixelAccum>()(acc_zero);
- while(src_begin!=src_end) {
- pixel_assigns_t<PixelAccum,PIXEL_DST_REF>()(
- inner_product_k<Size>(src_begin,ker_begin,acc_zero,
- pixel_plus_t<PixelAccum,PixelAccum,PixelAccum>(),
- pixel_multiplies_scalar_t<PIXEL_SRC_REF,kernel_type,PixelAccum>()),
- *dst_begin);
- ++src_begin; ++dst_begin;
- }
- return dst_begin;
- }
- /// \brief destination is set to be product of the source and a scalar
- template <typename PixelAccum,typename SrcView,typename Scalar,typename DstView>
- inline void view_multiplies_scalar(const SrcView& src,const Scalar& scalar,const DstView& dst) {
- BOOST_ASSERT(src.dimensions() == dst.dimensions());
- using PIXEL_SRC_REF = typename pixel_proxy<typename SrcView::value_type>::type;
- using PIXEL_DST_REF = typename pixel_proxy<typename DstView::value_type>::type;
- int height=src.height();
- for(int rr=0;rr<height;++rr) {
- typename SrcView::x_iterator it_src=src.row_begin(rr);
- typename DstView::x_iterator it_dst=dst.row_begin(rr);
- typename SrcView::x_iterator it_src_end=src.row_end(rr);
- while(it_src!=it_src_end) {
- pixel_assigns_t<PixelAccum,PIXEL_DST_REF>()(
- pixel_multiplies_scalar_t<PIXEL_SRC_REF,Scalar,PixelAccum>()(*it_src,scalar),
- *it_dst);
- ++it_src; ++it_dst;
- }
- }
- }
- }} // namespace boost::gil
- #endif
|