add boost on mac
This commit is contained in:
94
macx64/include/boost/gil/extension/numeric/affine.hpp
Normal file
94
macx64/include/boost/gil/extension/numeric/affine.hpp
Normal file
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// 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_AFFINE_HPP
|
||||
#define BOOST_GIL_EXTENSION_NUMERIC_AFFINE_HPP
|
||||
|
||||
#include <boost/gil/point.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Simple matrix to do 2D affine transformations. It is actually 3x3 but the last column is [0 0 1]
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
class matrix3x2 {
|
||||
public:
|
||||
matrix3x2() : a(1), b(0), c(0), d(1), e(0), f(0) {}
|
||||
matrix3x2(T A, T B, T C, T D, T E, T F) : a(A),b(B),c(C),d(D),e(E),f(F) {}
|
||||
matrix3x2(const matrix3x2& mat) : a(mat.a), b(mat.b), c(mat.c), d(mat.d), e(mat.e), f(mat.f) {}
|
||||
matrix3x2& operator=(const matrix3x2& m) { a=m.a; b=m.b; c=m.c; d=m.d; e=m.e; f=m.f; return *this; }
|
||||
|
||||
matrix3x2& operator*=(const matrix3x2& m) { (*this) = (*this)*m; return *this; }
|
||||
|
||||
static matrix3x2 get_rotate(T rads) { T c=std::cos(rads); T s=std::sin(rads); return matrix3x2(c,s,-s,c,0,0); }
|
||||
static matrix3x2 get_translate(point<T> const& t)
|
||||
{
|
||||
return matrix3x2(1, 0, 0, 1, t.x, t.y);
|
||||
}
|
||||
static matrix3x2 get_translate(T x, T y) { return matrix3x2(1 ,0,0,1 ,x, y ); }
|
||||
static matrix3x2 get_scale(point<T> const& s)
|
||||
{
|
||||
return matrix3x2(s.x, 0, 0, s.y, 0, 0);
|
||||
}
|
||||
static matrix3x2 get_scale(T x, T y) { return matrix3x2(x, 0,0,y, 0 ,0 ); }
|
||||
static matrix3x2 get_scale(T s) { return matrix3x2(s ,0,0,s ,0 ,0 ); }
|
||||
|
||||
T a,b,c,d,e,f;
|
||||
};
|
||||
|
||||
template <typename T> BOOST_FORCEINLINE
|
||||
matrix3x2<T> operator*(const matrix3x2<T>& m1, const matrix3x2<T>& m2) {
|
||||
return matrix3x2<T>(
|
||||
m1.a * m2.a + m1.b * m2.c,
|
||||
m1.a * m2.b + m1.b * m2.d,
|
||||
m1.c * m2.a + m1.d * m2.c,
|
||||
m1.c * m2.b + m1.d * m2.d,
|
||||
m1.e * m2.a + m1.f * m2.c + m2.e,
|
||||
m1.e * m2.b + m1.f * m2.d + m2.f );
|
||||
}
|
||||
|
||||
template <typename T, typename F>
|
||||
BOOST_FORCEINLINE
|
||||
point<F> operator*(point<T> const& p, matrix3x2<F> const& m)
|
||||
{
|
||||
return { m.a*p.x + m.c*p.y + m.e, m.b*p.x + m.d*p.y + m.f };
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Define affine mapping that transforms the source coordinates by the affine transformation
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
template <typename MapFn>
|
||||
concept MappingFunctionConcept {
|
||||
typename mapping_traits<MapFn>::result_type; where PointNDConcept<result_type>;
|
||||
|
||||
template <typename Domain> { where PointNDConcept<Domain> }
|
||||
result_type transform(MapFn&, const Domain& src);
|
||||
};
|
||||
*/
|
||||
|
||||
template <typename T> struct mapping_traits;
|
||||
|
||||
template <typename F>
|
||||
struct mapping_traits<matrix3x2<F>>
|
||||
{
|
||||
using result_type = point<F>;
|
||||
};
|
||||
|
||||
template <typename F, typename F2>
|
||||
BOOST_FORCEINLINE
|
||||
point<F> transform(matrix3x2<F> const& mat, point<F2> const& src)
|
||||
{
|
||||
return src * mat;
|
||||
}
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
149
macx64/include/boost/gil/extension/numeric/algorithm.hpp
Normal file
149
macx64/include/boost/gil/extension/numeric/algorithm.hpp
Normal file
@@ -0,0 +1,149 @@
|
||||
//
|
||||
// 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
|
||||
@@ -0,0 +1,147 @@
|
||||
//
|
||||
// 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_CHANNEL_NUMERIC_OPERATIONS_HPP
|
||||
#define BOOST_GIL_EXTENSION_NUMERIC_CHANNEL_NUMERIC_OPERATIONS_HPP
|
||||
|
||||
#include <boost/gil/channel.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// Structures for channel-wise numeric operations
|
||||
// Currently defined structures:
|
||||
// channel_plus_t (+), channel_minus_t (-),
|
||||
// channel_multiplies_t (*), channel_divides_t (/),
|
||||
// channel_plus_scalar_t (+s), channel_minus_scalar_t (-s),
|
||||
// channel_multiplies_scalar_t (*s), channel_divides_scalar_t (/s),
|
||||
// channel_halves_t (/=2), channel_zeros_t (=0), channel_assigns_t (=)
|
||||
|
||||
/// \ingroup ChannelNumericOperations
|
||||
/// structure for adding one channel to another
|
||||
/// this is a generic implementation; user should specialize it for better performance
|
||||
template <typename Channel1,typename Channel2,typename ChannelR>
|
||||
struct channel_plus_t {
|
||||
ChannelR operator()(typename channel_traits<Channel1>::const_reference ch1,
|
||||
typename channel_traits<Channel2>::const_reference ch2) const {
|
||||
return ChannelR(ch1)+ChannelR(ch2);
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ChannelNumericOperations
|
||||
/// structure for subtracting one channel from another
|
||||
/// this is a generic implementation; user should specialize it for better performance
|
||||
template <typename Channel1,typename Channel2,typename ChannelR>
|
||||
struct channel_minus_t {
|
||||
ChannelR operator()(typename channel_traits<Channel1>::const_reference ch1,
|
||||
typename channel_traits<Channel2>::const_reference ch2) const {
|
||||
return ChannelR(ch1)-ChannelR(ch2);
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ChannelNumericOperations
|
||||
/// structure for multiplying one channel to another
|
||||
/// this is a generic implementation; user should specialize it for better performance
|
||||
template <typename Channel1,typename Channel2,typename ChannelR>
|
||||
struct channel_multiplies_t {
|
||||
ChannelR operator()(typename channel_traits<Channel1>::const_reference ch1,
|
||||
typename channel_traits<Channel2>::const_reference ch2) const {
|
||||
return ChannelR(ch1)*ChannelR(ch2);
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ChannelNumericOperations
|
||||
/// structure for dividing channels
|
||||
/// this is a generic implementation; user should specialize it for better performance
|
||||
template <typename Channel1,typename Channel2,typename ChannelR>
|
||||
struct channel_divides_t {
|
||||
ChannelR operator()(typename channel_traits<Channel1>::const_reference ch1,
|
||||
typename channel_traits<Channel2>::const_reference ch2) const {
|
||||
return ChannelR(ch1)/ChannelR(ch2);
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ChannelNumericOperations
|
||||
/// structure for adding a scalar to a channel
|
||||
/// this is a generic implementation; user should specialize it for better performance
|
||||
template <typename Channel,typename Scalar,typename ChannelR>
|
||||
struct channel_plus_scalar_t {
|
||||
ChannelR operator()(typename channel_traits<Channel>::const_reference ch,
|
||||
const Scalar& s) const {
|
||||
return ChannelR(ch)+ChannelR(s);
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ChannelNumericOperations
|
||||
/// structure for subtracting a scalar from a channel
|
||||
/// this is a generic implementation; user should specialize it for better performance
|
||||
template <typename Channel,typename Scalar,typename ChannelR>
|
||||
struct channel_minus_scalar_t {
|
||||
ChannelR operator()(typename channel_traits<Channel>::const_reference ch,
|
||||
const Scalar& s) const {
|
||||
return ChannelR(ch-s);
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ChannelNumericOperations
|
||||
/// structure for multiplying a scalar to one channel
|
||||
/// this is a generic implementation; user should specialize it for better performance
|
||||
template <typename Channel,typename Scalar,typename ChannelR>
|
||||
struct channel_multiplies_scalar_t {
|
||||
ChannelR operator()(typename channel_traits<Channel>::const_reference ch,
|
||||
const Scalar& s) const {
|
||||
return ChannelR(ch)*ChannelR(s);
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ChannelNumericOperations
|
||||
/// structure for dividing a channel by a scalar
|
||||
/// this is a generic implementation; user should specialize it for better performance
|
||||
template <typename Channel,typename Scalar,typename ChannelR>
|
||||
struct channel_divides_scalar_t {
|
||||
ChannelR operator()(typename channel_traits<Channel>::const_reference ch,
|
||||
const Scalar& s) const {
|
||||
return ChannelR(ch)/ChannelR(s);
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ChannelNumericOperations
|
||||
/// structure for halving a channel
|
||||
/// this is a generic implementation; user should specialize it for better performance
|
||||
template <typename Channel>
|
||||
struct channel_halves_t {
|
||||
typename channel_traits<Channel>::reference
|
||||
operator()(typename channel_traits<Channel>::reference ch) const {
|
||||
return ch/=2.0;
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ChannelNumericOperations
|
||||
/// structure for setting a channel to zero
|
||||
/// this is a generic implementation; user should specialize it for better performance
|
||||
template <typename Channel>
|
||||
struct channel_zeros_t {
|
||||
typename channel_traits<Channel>::reference
|
||||
operator()(typename channel_traits<Channel>::reference ch) const {
|
||||
return ch=Channel(0);
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup ChannelNumericOperations
|
||||
/// structure for assigning one channel to another
|
||||
/// this is a generic implementation; user should specialize it for better performance
|
||||
template <typename Channel1,typename Channel2>
|
||||
struct channel_assigns_t {
|
||||
typename channel_traits<Channel2>::reference
|
||||
operator()(typename channel_traits<Channel1>::const_reference ch1,
|
||||
typename channel_traits<Channel2>::reference ch2) const {
|
||||
return ch2=Channel2(ch1);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
217
macx64/include/boost/gil/extension/numeric/convolve.hpp
Normal file
217
macx64/include/boost/gil/extension/numeric/convolve.hpp
Normal file
@@ -0,0 +1,217 @@
|
||||
//
|
||||
// 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_CONVOLVE_HPP
|
||||
#define BOOST_GIL_EXTENSION_NUMERIC_CONVOLVE_HPP
|
||||
|
||||
#include <boost/gil/extension/numeric/algorithm.hpp>
|
||||
#include <boost/gil/extension/numeric/kernel.hpp>
|
||||
#include <boost/gil/extension/numeric/pixel_numeric_operations.hpp>
|
||||
|
||||
#include <boost/gil/algorithm.hpp>
|
||||
#include <boost/gil/image_view_factory.hpp>
|
||||
#include <boost/gil/metafunctions.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// 2D seperable convolutions and correlations
|
||||
|
||||
/// \ingroup ImageAlgorithms
|
||||
/// Boundary options for 1D correlations/convolutions
|
||||
enum convolve_boundary_option {
|
||||
convolve_option_output_ignore, /// do nothing to the output
|
||||
convolve_option_output_zero, /// set the output to zero
|
||||
convolve_option_extend_padded, /// assume the source boundaries to be padded already
|
||||
convolve_option_extend_zero, /// assume the source boundaries to be zero
|
||||
convolve_option_extend_constant /// assume the source boundaries to be the boundary value
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
/// compute the correlation of 1D kernel with the rows of an image
|
||||
template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView,typename Correlator>
|
||||
void correlate_rows_imp(const SrcView& src, const Kernel& ker, const DstView& dst,
|
||||
convolve_boundary_option option,
|
||||
Correlator correlator) {
|
||||
BOOST_ASSERT(src.dimensions() == dst.dimensions());
|
||||
BOOST_ASSERT(ker.size() != 0);
|
||||
|
||||
using PIXEL_SRC_REF = typename pixel_proxy<typename SrcView::value_type>::type;
|
||||
using PIXEL_DST_REF = typename pixel_proxy<typename DstView::value_type>::type;
|
||||
|
||||
if(ker.size()==1) {//reduces to a multiplication
|
||||
view_multiplies_scalar<PixelAccum>(src,*ker.begin(),dst);
|
||||
return;
|
||||
}
|
||||
|
||||
int width=src.width(),height=src.height();
|
||||
PixelAccum acc_zero; pixel_zeros_t<PixelAccum>()(acc_zero);
|
||||
if (width==0) return;
|
||||
if (option==convolve_option_output_ignore || option==convolve_option_output_zero) {
|
||||
typename DstView::value_type dst_zero; pixel_assigns_t<PixelAccum,PIXEL_DST_REF>()(acc_zero,dst_zero);
|
||||
if (width<(int)ker.size()) {
|
||||
if (option==convolve_option_output_zero)
|
||||
fill_pixels(dst,dst_zero);
|
||||
} else {
|
||||
std::vector<PixelAccum> buffer(width);
|
||||
for(int rr=0;rr<height;++rr) {
|
||||
assign_pixels(src.row_begin(rr),src.row_end(rr),&buffer.front());
|
||||
typename DstView::x_iterator it_dst=dst.row_begin(rr);
|
||||
if (option==convolve_option_output_zero)
|
||||
std::fill_n(it_dst,ker.left_size(),dst_zero);
|
||||
it_dst+=ker.left_size();
|
||||
correlator(&buffer.front(),&buffer.front()+width+1-ker.size(),
|
||||
ker.begin(),it_dst);
|
||||
it_dst+=width+1-ker.size();
|
||||
if (option==convolve_option_output_zero)
|
||||
std::fill_n(it_dst,ker.right_size(),dst_zero);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::vector<PixelAccum> buffer(width+ker.size()-1);
|
||||
for(int rr=0;rr<height;++rr) {
|
||||
PixelAccum* it_buffer=&buffer.front();
|
||||
if (option==convolve_option_extend_padded) {
|
||||
assign_pixels(src.row_begin(rr)-ker.left_size(),
|
||||
src.row_end(rr)+ker.right_size(),
|
||||
it_buffer);
|
||||
} else if (option==convolve_option_extend_zero) {
|
||||
std::fill_n(it_buffer,ker.left_size(),acc_zero);
|
||||
it_buffer+=ker.left_size();
|
||||
assign_pixels(src.row_begin(rr),src.row_end(rr),it_buffer);
|
||||
it_buffer+=width;
|
||||
std::fill_n(it_buffer,ker.right_size(),acc_zero);
|
||||
} else if (option==convolve_option_extend_constant) {
|
||||
PixelAccum filler;
|
||||
pixel_assigns_t<PIXEL_SRC_REF,PixelAccum>()(*src.row_begin(rr),filler);
|
||||
std::fill_n(it_buffer,ker.left_size(),filler);
|
||||
it_buffer+=ker.left_size();
|
||||
assign_pixels(src.row_begin(rr),src.row_end(rr),it_buffer);
|
||||
it_buffer+=width;
|
||||
pixel_assigns_t<PIXEL_SRC_REF,PixelAccum>()(src.row_end(rr)[-1],filler);
|
||||
std::fill_n(it_buffer,ker.right_size(),filler);
|
||||
}
|
||||
correlator(&buffer.front(),&buffer.front()+width,
|
||||
ker.begin(),
|
||||
dst.row_begin(rr));
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename PixelAccum>
|
||||
class correlator_n {
|
||||
private:
|
||||
std::size_t _size;
|
||||
public:
|
||||
correlator_n(std::size_t size_in) : _size(size_in) {}
|
||||
template <typename SrcIterator,typename KernelIterator,typename DstIterator>
|
||||
void operator()(SrcIterator src_begin,SrcIterator src_end,
|
||||
KernelIterator ker_begin,
|
||||
DstIterator dst_begin) {
|
||||
correlate_pixels_n<PixelAccum>(src_begin,src_end,ker_begin,_size,dst_begin);
|
||||
}
|
||||
};
|
||||
template <std::size_t Size,typename PixelAccum>
|
||||
struct correlator_k {
|
||||
public:
|
||||
template <typename SrcIterator,typename KernelIterator,typename DstIterator>
|
||||
void operator()(SrcIterator src_begin,SrcIterator src_end,
|
||||
KernelIterator ker_begin,
|
||||
DstIterator dst_begin){
|
||||
correlate_pixels_k<Size,PixelAccum>(src_begin,src_end,ker_begin,dst_begin);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/// \ingroup ImageAlgorithms
|
||||
///correlate a 1D variable-size kernel along the rows of an image
|
||||
template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
|
||||
BOOST_FORCEINLINE
|
||||
void correlate_rows(const SrcView& src, const Kernel& ker, const DstView& dst,
|
||||
convolve_boundary_option option=convolve_option_extend_zero) {
|
||||
detail::correlate_rows_imp<PixelAccum>(src,ker,dst,option,detail::correlator_n<PixelAccum>(ker.size()));
|
||||
}
|
||||
|
||||
/// \ingroup ImageAlgorithms
|
||||
///correlate a 1D variable-size kernel along the columns of an image
|
||||
template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
|
||||
BOOST_FORCEINLINE
|
||||
void correlate_cols(const SrcView& src, const Kernel& ker, const DstView& dst,
|
||||
convolve_boundary_option option=convolve_option_extend_zero) {
|
||||
correlate_rows<PixelAccum>(transposed_view(src),ker,transposed_view(dst),option);
|
||||
}
|
||||
|
||||
/// \ingroup ImageAlgorithms
|
||||
///convolve a 1D variable-size kernel along the rows of an image
|
||||
template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
|
||||
BOOST_FORCEINLINE
|
||||
void convolve_rows(const SrcView& src, const Kernel& ker, const DstView& dst,
|
||||
convolve_boundary_option option=convolve_option_extend_zero) {
|
||||
correlate_rows<PixelAccum>(src,reverse_kernel(ker),dst,option);
|
||||
}
|
||||
|
||||
/// \ingroup ImageAlgorithms
|
||||
///convolve a 1D variable-size kernel along the columns of an image
|
||||
template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
|
||||
BOOST_FORCEINLINE
|
||||
void convolve_cols(const SrcView& src, const Kernel& ker, const DstView& dst,
|
||||
convolve_boundary_option option=convolve_option_extend_zero) {
|
||||
convolve_rows<PixelAccum>(transposed_view(src),ker,transposed_view(dst),option);
|
||||
}
|
||||
|
||||
/// \ingroup ImageAlgorithms
|
||||
///correlate a 1D fixed-size kernel along the rows of an image
|
||||
template <typename PixelAccum, typename SrcView, typename Kernel, typename DstView>
|
||||
BOOST_FORCEINLINE
|
||||
void correlate_rows_fixed(const SrcView& src, const Kernel& kernel, const DstView& dst,
|
||||
convolve_boundary_option option=convolve_option_extend_zero)
|
||||
{
|
||||
using correlator = detail::correlator_k
|
||||
<
|
||||
std::extent<Kernel>::value,
|
||||
PixelAccum
|
||||
>;
|
||||
detail::correlate_rows_imp<PixelAccum>(
|
||||
src, kernel, dst, option, correlator{});
|
||||
}
|
||||
|
||||
/// \ingroup ImageAlgorithms
|
||||
///correlate a 1D fixed-size kernel along the columns of an image
|
||||
template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
|
||||
BOOST_FORCEINLINE
|
||||
void correlate_cols_fixed(const SrcView& src, const Kernel& ker, const DstView& dst,
|
||||
convolve_boundary_option option=convolve_option_extend_zero) {
|
||||
correlate_rows_fixed<PixelAccum>(transposed_view(src),ker,transposed_view(dst),option);
|
||||
}
|
||||
|
||||
/// \ingroup ImageAlgorithms
|
||||
///convolve a 1D fixed-size kernel along the rows of an image
|
||||
template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
|
||||
BOOST_FORCEINLINE
|
||||
void convolve_rows_fixed(const SrcView& src, const Kernel& ker, const DstView& dst,
|
||||
convolve_boundary_option option=convolve_option_extend_zero) {
|
||||
correlate_rows_fixed<PixelAccum>(src,reverse_kernel(ker),dst,option);
|
||||
}
|
||||
|
||||
/// \ingroup ImageAlgorithms
|
||||
///convolve a 1D fixed-size kernel along the columns of an image
|
||||
template <typename PixelAccum,typename SrcView,typename Kernel,typename DstView>
|
||||
BOOST_FORCEINLINE
|
||||
void convolve_cols_fixed(const SrcView& src, const Kernel& ker, const DstView& dst,
|
||||
convolve_boundary_option option=convolve_option_extend_zero) {
|
||||
convolve_rows_fixed<PixelAccum>(transposed_view(src),ker,transposed_view(dst),option);
|
||||
}
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
118
macx64/include/boost/gil/extension/numeric/kernel.hpp
Normal file
118
macx64/include/boost/gil/extension/numeric/kernel.hpp
Normal file
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// 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_KERNEL_HPP
|
||||
#define BOOST_GIL_EXTENSION_NUMERIC_KERNEL_HPP
|
||||
|
||||
#include <boost/gil/utilities.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// Definitions of 1D fixed-size and variable-size kernels and related operations
|
||||
|
||||
namespace detail {
|
||||
|
||||
/// \brief kernel adaptor for one-dimensional cores
|
||||
/// Core needs to provide size(),begin(),end(),operator[],
|
||||
/// value_type,iterator,const_iterator,reference,const_reference
|
||||
template <typename Core>
|
||||
class kernel_1d_adaptor : public Core {
|
||||
private:
|
||||
std::size_t _center;
|
||||
public:
|
||||
kernel_1d_adaptor() : _center(0) {}
|
||||
|
||||
explicit kernel_1d_adaptor(std::size_t center_in)
|
||||
: _center(center_in)
|
||||
{
|
||||
BOOST_ASSERT(_center < this->size());
|
||||
}
|
||||
|
||||
kernel_1d_adaptor(std::size_t size_in, std::size_t center_in)
|
||||
: Core(size_in)
|
||||
, _center(center_in)
|
||||
{
|
||||
BOOST_ASSERT(_center < this->size());
|
||||
}
|
||||
|
||||
kernel_1d_adaptor(kernel_1d_adaptor const& k_in) : Core(k_in), _center(k_in._center) {}
|
||||
|
||||
kernel_1d_adaptor& operator=(const kernel_1d_adaptor& k_in) {
|
||||
Core::operator=(k_in);
|
||||
_center=k_in._center;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::size_t left_size() const
|
||||
{
|
||||
BOOST_ASSERT(_center < this->size());
|
||||
return _center;
|
||||
}
|
||||
|
||||
std::size_t right_size() const
|
||||
{
|
||||
BOOST_ASSERT(_center < this->size());
|
||||
return this->size() - _center - 1;
|
||||
}
|
||||
|
||||
std::size_t& center() {return _center;}
|
||||
const std::size_t& center() const {return _center;}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \brief variable-size kernel
|
||||
template <typename T, typename Alloc = std::allocator<T> >
|
||||
class kernel_1d : public detail::kernel_1d_adaptor<std::vector<T,Alloc>>
|
||||
{
|
||||
using parent_t = detail::kernel_1d_adaptor<std::vector<T,Alloc>>;
|
||||
public:
|
||||
kernel_1d() {}
|
||||
kernel_1d(std::size_t size_in,std::size_t center_in) : parent_t(size_in,center_in) {}
|
||||
template <typename FwdIterator>
|
||||
kernel_1d(FwdIterator elements, std::size_t size_in, std::size_t center_in) : parent_t(size_in,center_in) {
|
||||
detail::copy_n(elements,size_in,this->begin());
|
||||
}
|
||||
kernel_1d(const kernel_1d& k_in) : parent_t(k_in) {}
|
||||
};
|
||||
|
||||
/// \brief static-size kernel
|
||||
template <typename T,std::size_t Size>
|
||||
class kernel_1d_fixed : public detail::kernel_1d_adaptor<std::array<T,Size>>
|
||||
{
|
||||
using parent_t = detail::kernel_1d_adaptor<std::array<T,Size>>;
|
||||
public:
|
||||
kernel_1d_fixed() {}
|
||||
explicit kernel_1d_fixed(std::size_t center_in) : parent_t(center_in) {}
|
||||
|
||||
template <typename FwdIterator>
|
||||
explicit kernel_1d_fixed(FwdIterator elements, std::size_t center_in) : parent_t(center_in) {
|
||||
detail::copy_n(elements,Size,this->begin());
|
||||
}
|
||||
kernel_1d_fixed(const kernel_1d_fixed& k_in) : parent_t(k_in) {}
|
||||
};
|
||||
|
||||
/// \brief reverse a kernel
|
||||
template <typename Kernel>
|
||||
inline Kernel reverse_kernel(const Kernel& kernel) {
|
||||
Kernel result(kernel);
|
||||
result.center()=kernel.right_size();
|
||||
std::reverse(result.begin(), result.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,172 @@
|
||||
//
|
||||
// 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_PIXEL_NUMERIC_OPERATIONS_HPP
|
||||
#define BOOST_GIL_EXTENSION_NUMERIC_PIXEL_NUMERIC_OPERATIONS_HPP
|
||||
|
||||
#include <boost/gil/extension/numeric/channel_numeric_operations.hpp>
|
||||
|
||||
#include <boost/gil/color_base_algorithm.hpp>
|
||||
#include <boost/gil/pixel.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// Structures for pixel-wise numeric operations
|
||||
// Currently defined structures:
|
||||
// pixel_plus_t (+), pixel_minus_t (-)
|
||||
// pixel_multiplies_scalar_t (*), pixel_divides_scalar_t (/)
|
||||
// pixel_halves_t (/=2), pixel_zeros_t (=0)
|
||||
// pixel_assigns_t (=)
|
||||
|
||||
/// \ingroup PixelNumericOperations
|
||||
/// \brief construct for adding two pixels
|
||||
template <typename PixelRef1, // models pixel concept
|
||||
typename PixelRef2, // models pixel concept
|
||||
typename PixelR> // models pixel value concept
|
||||
struct pixel_plus_t {
|
||||
PixelR operator() (const PixelRef1& p1,
|
||||
const PixelRef2& p2) const {
|
||||
PixelR result;
|
||||
static_transform(p1,p2,result,
|
||||
channel_plus_t<typename channel_type<PixelRef1>::type,
|
||||
typename channel_type<PixelRef2>::type,
|
||||
typename channel_type<PixelR>::type>());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup PixelNumericOperations
|
||||
/// \brief construct for subtracting two pixels
|
||||
template <typename PixelRef1, // models pixel concept
|
||||
typename PixelRef2, // models pixel concept
|
||||
typename PixelR> // models pixel value concept
|
||||
struct pixel_minus_t {
|
||||
PixelR operator() (const PixelRef1& p1,
|
||||
const PixelRef2& p2) const {
|
||||
PixelR result;
|
||||
static_transform(p1,p2,result,
|
||||
channel_minus_t<typename channel_type<PixelRef1>::type,
|
||||
typename channel_type<PixelRef2>::type,
|
||||
typename channel_type<PixelR>::type>());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup PixelNumericOperations
|
||||
/// \brief construct for multiplying scalar to a pixel
|
||||
template <typename PixelRef, // models pixel concept
|
||||
typename Scalar, // models a scalar type
|
||||
typename PixelR> // models pixel value concept
|
||||
struct pixel_multiplies_scalar_t {
|
||||
PixelR operator () (const PixelRef& p,
|
||||
const Scalar& s) const {
|
||||
PixelR result;
|
||||
static_transform(p,result,
|
||||
std::bind(channel_multiplies_scalar_t<typename channel_type<PixelRef>::type,
|
||||
Scalar,
|
||||
typename channel_type<PixelR>::type>(),
|
||||
std::placeholders::_1, s));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup PixelNumericOperations
|
||||
/// \brief construct for dividing two pixels
|
||||
template <typename PixelRef1, // models pixel concept
|
||||
typename PixelRef2, // models pixel concept
|
||||
typename PixelR> // models pixel value concept
|
||||
struct pixel_multiply_t {
|
||||
PixelR operator() (const PixelRef1& p1,
|
||||
const PixelRef2& p2) const {
|
||||
PixelR result;
|
||||
static_transform(p1,p2,result,
|
||||
channel_multiplies_t<typename channel_type<PixelRef1>::type,
|
||||
typename channel_type<PixelRef2>::type,
|
||||
typename channel_type<PixelR>::type>());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup PixelNumericOperations
|
||||
/// \brief construct for dividing a pixel by a scalar
|
||||
template <typename PixelRef, // models pixel concept
|
||||
typename Scalar, // models a scalar type
|
||||
typename PixelR> // models pixel value concept
|
||||
struct pixel_divides_scalar_t {
|
||||
PixelR operator () (const PixelRef& p,
|
||||
const Scalar& s) const {
|
||||
PixelR result;
|
||||
static_transform(p,result,
|
||||
std::bind(channel_divides_scalar_t<typename channel_type<PixelRef>::type,
|
||||
Scalar,
|
||||
typename channel_type<PixelR>::type>(),
|
||||
std::placeholders::_1, s));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup PixelNumericOperations
|
||||
/// \brief construct for dividing two pixels
|
||||
template <typename PixelRef1, // models pixel concept
|
||||
typename PixelRef2, // models pixel concept
|
||||
typename PixelR> // models pixel value concept
|
||||
struct pixel_divide_t {
|
||||
PixelR operator() (const PixelRef1& p1,
|
||||
const PixelRef2& p2) const {
|
||||
PixelR result;
|
||||
static_transform(p1,p2,result,
|
||||
channel_divides_t<typename channel_type<PixelRef1>::type,
|
||||
typename channel_type<PixelRef2>::type,
|
||||
typename channel_type<PixelR>::type>());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup PixelNumericOperations
|
||||
/// \brief construct for dividing a pixel by 2
|
||||
template <typename PixelRef> // models pixel concept
|
||||
struct pixel_halves_t {
|
||||
PixelRef& operator () (PixelRef& p) const {
|
||||
static_for_each(p,channel_halves_t<typename channel_type<PixelRef>::type>());
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup PixelNumericOperations
|
||||
/// \brief construct for setting a pixel to zero (for whatever zero means)
|
||||
template <typename PixelRef> // models pixel concept
|
||||
struct pixel_zeros_t {
|
||||
PixelRef& operator () (PixelRef& p) const {
|
||||
static_for_each(p,channel_zeros_t<typename channel_type<PixelRef>::type>());
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
// Hailin: This is how you can do it:
|
||||
template <typename Pixel>
|
||||
void zero_channels(Pixel& p) {
|
||||
static_for_each(p,channel_zeros_t<typename channel_type<Pixel>::type>());
|
||||
}
|
||||
|
||||
|
||||
/// \ingroup PixelNumericOperations
|
||||
///definition and a generic implementation for casting and assigning a pixel to another
|
||||
///user should specialize it for better performance
|
||||
template <typename PixelRef, // models pixel concept
|
||||
typename PixelRefR> // models pixel concept
|
||||
struct pixel_assigns_t {
|
||||
PixelRefR operator () (const PixelRef& src,
|
||||
PixelRefR& dst) const {
|
||||
static_for_each(src,dst,channel_assigns_t<typename channel_type<PixelRef>::type,
|
||||
typename channel_type<PixelRefR>::type>());
|
||||
return dst;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
143
macx64/include/boost/gil/extension/numeric/resample.hpp
Normal file
143
macx64/include/boost/gil/extension/numeric/resample.hpp
Normal file
@@ -0,0 +1,143 @@
|
||||
//
|
||||
// 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_RESAMPLE_HPP
|
||||
#define BOOST_GIL_EXTENSION_NUMERIC_RESAMPLE_HPP
|
||||
|
||||
#include <boost/gil/extension/numeric/affine.hpp>
|
||||
#include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// Support for generic image resampling
|
||||
// NOTE: The code is for example use only. It is not optimized for performance
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
////
|
||||
//// resample_pixels: set each pixel in the destination view as the result of a sampling function over the transformed coordinates of the source view
|
||||
////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename MapFn> struct mapping_traits {};
|
||||
|
||||
/// \brief Set each pixel in the destination view as the result of a sampling function over the transformed coordinates of the source view
|
||||
/// \ingroup ImageAlgorithms
|
||||
///
|
||||
/// The provided implementation works for 2D image views only
|
||||
template <typename Sampler, // Models SamplerConcept
|
||||
typename SrcView, // Models RandomAccess2DImageViewConcept
|
||||
typename DstView, // Models MutableRandomAccess2DImageViewConcept
|
||||
typename MapFn> // Models MappingFunctionConcept
|
||||
void resample_pixels(const SrcView& src_view, const DstView& dst_view, const MapFn& dst_to_src, Sampler sampler=Sampler())
|
||||
{
|
||||
typename DstView::point_t dst_dims=dst_view.dimensions();
|
||||
typename DstView::point_t dst_p;
|
||||
|
||||
for (dst_p.y=0; dst_p.y<dst_dims.y; ++dst_p.y) {
|
||||
typename DstView::x_iterator xit = dst_view.row_begin(dst_p.y);
|
||||
for (dst_p.x=0; dst_p.x<dst_dims.x; ++dst_p.x) {
|
||||
sample(sampler, src_view, transform(dst_to_src, dst_p), xit[dst_p.x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
////
|
||||
//// resample_pixels when one or both image views are run-time instantiated.
|
||||
////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace detail {
|
||||
template <typename Sampler, typename MapFn>
|
||||
struct resample_pixels_fn : public binary_operation_obj<resample_pixels_fn<Sampler,MapFn> > {
|
||||
MapFn _dst_to_src;
|
||||
Sampler _sampler;
|
||||
resample_pixels_fn(const MapFn& dst_to_src, const Sampler& sampler) : _dst_to_src(dst_to_src), _sampler(sampler) {}
|
||||
|
||||
template <typename SrcView, typename DstView> BOOST_FORCEINLINE void apply_compatible(const SrcView& src, const DstView& dst) const {
|
||||
resample_pixels(src, dst, _dst_to_src, _sampler);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief resample_pixels when the source is run-time specified
|
||||
/// If invoked on incompatible views, throws std::bad_cast()
|
||||
/// \ingroup ImageAlgorithms
|
||||
template <typename Sampler, typename Types1, typename V2, typename MapFn>
|
||||
void resample_pixels(const any_image_view<Types1>& src, const V2& dst, const MapFn& dst_to_src, Sampler sampler=Sampler())
|
||||
{
|
||||
apply_operation(src, std::bind(
|
||||
detail::resample_pixels_fn<Sampler, MapFn>(dst_to_src, sampler),
|
||||
std::placeholders::_1,
|
||||
dst));
|
||||
}
|
||||
|
||||
/// \brief resample_pixels when the destination is run-time specified
|
||||
/// If invoked on incompatible views, throws std::bad_cast()
|
||||
/// \ingroup ImageAlgorithms
|
||||
template <typename Sampler, typename V1, typename Types2, typename MapFn>
|
||||
void resample_pixels(const V1& src, const any_image_view<Types2>& dst, const MapFn& dst_to_src, Sampler sampler=Sampler())
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
apply_operation(dst, std::bind(
|
||||
detail::resample_pixels_fn<Sampler, MapFn>(dst_to_src, sampler),
|
||||
src,
|
||||
std::placeholders::_1));
|
||||
}
|
||||
|
||||
/// \brief resample_pixels when both the source and the destination are run-time specified
|
||||
/// If invoked on incompatible views, throws std::bad_cast()
|
||||
/// \ingroup ImageAlgorithms
|
||||
template <typename Sampler, typename SrcTypes, typename DstTypes, typename MapFn>
|
||||
void resample_pixels(const any_image_view<SrcTypes>& src, const any_image_view<DstTypes>& dst, const MapFn& dst_to_src, Sampler sampler=Sampler()) {
|
||||
apply_operation(src,dst,detail::resample_pixels_fn<Sampler,MapFn>(dst_to_src,sampler));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
////
|
||||
//// resample_subimage: copy into the destination a rotated rectangular region from the source, rescaling it to fit into the destination
|
||||
////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Extract into dst the rotated bounds [src_min..src_max] rotated at 'angle' from the source view 'src'
|
||||
// The source coordinates are in the coordinate space of the source image
|
||||
// Note that the views could also be variants (i.e. any_image_view)
|
||||
template <typename Sampler, typename SrcMetaView, typename DstMetaView>
|
||||
void resample_subimage(const SrcMetaView& src, const DstMetaView& dst,
|
||||
double src_min_x, double src_min_y,
|
||||
double src_max_x, double src_max_y,
|
||||
double angle, const Sampler& sampler=Sampler()) {
|
||||
double src_width = std::max<double>(src_max_x - src_min_x - 1,1);
|
||||
double src_height = std::max<double>(src_max_y - src_min_y - 1,1);
|
||||
double dst_width = std::max<double>((double)(dst.width()-1),1);
|
||||
double dst_height = std::max<double>((double)(dst.height()-1),1);
|
||||
|
||||
matrix3x2<double> mat =
|
||||
matrix3x2<double>::get_translate(-dst_width/2.0, -dst_height/2.0) *
|
||||
matrix3x2<double>::get_scale(src_width / dst_width, src_height / dst_height)*
|
||||
matrix3x2<double>::get_rotate(-angle)*
|
||||
matrix3x2<double>::get_translate(src_min_x + src_width/2.0, src_min_y + src_height/2.0);
|
||||
resample_pixels(src,dst,mat,sampler);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
////
|
||||
//// resize_view: Copy the source view into the destination, scaling to fit
|
||||
////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename Sampler, typename SrcMetaView, typename DstMetaView>
|
||||
void resize_view(const SrcMetaView& src, const DstMetaView& dst, const Sampler& sampler=Sampler()) {
|
||||
resample_subimage(src,dst,0.0,0.0,(double)src.width(),(double)src.height(),0.0,sampler);
|
||||
}
|
||||
|
||||
} } // namespace boost::gil
|
||||
|
||||
#endif // BOOST_GIL_EXTENSION_NUMERIC_RESAMPLE_HPP
|
||||
189
macx64/include/boost/gil/extension/numeric/sampler.hpp
Normal file
189
macx64/include/boost/gil/extension/numeric/sampler.hpp
Normal file
@@ -0,0 +1,189 @@
|
||||
//
|
||||
// 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_SAMPLER_HPP
|
||||
#define BOOST_GIL_EXTENSION_NUMERIC_SAMPLER_HPP
|
||||
|
||||
#include <boost/gil/extension/numeric/pixel_numeric_operations.hpp>
|
||||
#include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
|
||||
|
||||
namespace boost { namespace gil {
|
||||
|
||||
// Nearest-neighbor and bilinear image samplers.
|
||||
// NOTE: The code is for example use only. It is not optimized for performance
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
////
|
||||
//// resample_pixels: set each pixel in the destination view as the result of a sampling function over the transformed coordinates of the source view
|
||||
////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
template <typename Sampler>
|
||||
concept SamplerConcept {
|
||||
template <typename DstP, // Models PixelConcept
|
||||
typename SrcView, // Models RandomAccessNDImageViewConcept
|
||||
typename S_COORDS> // Models PointNDConcept, where S_COORDS::num_dimensions == SrcView::num_dimensions
|
||||
bool sample(const Sampler& s, const SrcView& src, const S_COORDS& p, DstP result);
|
||||
};
|
||||
*/
|
||||
|
||||
/// \brief A sampler that sets the destination pixel to the closest one in the source. If outside the bounds, it doesn't change the destination
|
||||
/// \ingroup ImageAlgorithms
|
||||
struct nearest_neighbor_sampler {};
|
||||
|
||||
template <typename DstP, typename SrcView, typename F>
|
||||
bool sample(nearest_neighbor_sampler, SrcView const& src, point<F> const& p, DstP& result)
|
||||
{
|
||||
typename SrcView::point_t center(iround(p));
|
||||
if (center.x >= 0 && center.y >= 0 && center.x < src.width() && center.y < src.height())
|
||||
{
|
||||
result=src(center.x,center.y);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct cast_channel_fn {
|
||||
template <typename SrcChannel, typename DstChannel>
|
||||
void operator()(const SrcChannel& src, DstChannel& dst) {
|
||||
using dst_value_t = typename channel_traits<DstChannel>::value_type;
|
||||
dst = dst_value_t(src);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename SrcPixel, typename DstPixel>
|
||||
void cast_pixel(const SrcPixel& src, DstPixel& dst) {
|
||||
static_for_each(src,dst,cast_channel_fn());
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Weight>
|
||||
struct add_dst_mul_src_channel {
|
||||
Weight _w;
|
||||
add_dst_mul_src_channel(Weight w) : _w(w) {}
|
||||
|
||||
template <typename SrcChannel, typename DstChannel>
|
||||
void operator()(const SrcChannel& src, DstChannel& dst) const {
|
||||
dst += DstChannel(src*_w);
|
||||
}
|
||||
};
|
||||
|
||||
// dst += DST_TYPE(src * w)
|
||||
template <typename SrcP,typename Weight,typename DstP>
|
||||
struct add_dst_mul_src {
|
||||
void operator()(const SrcP& src, Weight weight, DstP& dst) const {
|
||||
static_for_each(src,dst, add_dst_mul_src_channel<Weight>(weight));
|
||||
// pixel_assigns_t<DstP,DstP&>()(
|
||||
// pixel_plus_t<DstP,DstP,DstP>()(
|
||||
// pixel_multiplies_scalar_t<SrcP,Weight,DstP>()(src,weight),
|
||||
// dst),
|
||||
// dst);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/// \brief A sampler that sets the destination pixel as the bilinear interpolation of the four closest pixels from the source.
|
||||
/// If outside the bounds, it doesn't change the destination
|
||||
/// \ingroup ImageAlgorithms
|
||||
struct bilinear_sampler {};
|
||||
|
||||
template <typename DstP, typename SrcView, typename F>
|
||||
bool sample(bilinear_sampler, SrcView const& src, point<F> const& p, DstP& result)
|
||||
{
|
||||
using SrcP = typename SrcView::value_type;
|
||||
point_t p0(ifloor(p.x), ifloor(p.y)); // the closest integer coordinate top left from p
|
||||
point<F> frac(p.x-p0.x, p.y-p0.y);
|
||||
|
||||
if (p0.x < -1 || p0.y < -1 || p0.x>=src.width() || p0.y>=src.height())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pixel<F,devicen_layout_t<num_channels<SrcView>::value> > mp(0); // suboptimal
|
||||
typename SrcView::xy_locator loc=src.xy_at(p0.x,p0.y);
|
||||
|
||||
if (p0.x == -1)
|
||||
{
|
||||
if (p0.y == -1)
|
||||
{
|
||||
// the top-left corner pixel
|
||||
++loc.y();
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], 1 ,mp);
|
||||
}
|
||||
else if (p0.y+1<src.height())
|
||||
{
|
||||
// on the first column, but not the top-left nor bottom-left corner pixel
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], (1-frac.y),mp);
|
||||
++loc.y();
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.y ,mp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the bottom-left corner pixel
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], 1 ,mp);
|
||||
}
|
||||
}
|
||||
else if (p0.x+1<src.width())
|
||||
{
|
||||
if (p0.y == -1)
|
||||
{
|
||||
// on the first row, but not the top-left nor top-right corner pixel
|
||||
++loc.y();
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x) ,mp);
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x ,mp);
|
||||
}
|
||||
else if (p0.y+1<src.height())
|
||||
{
|
||||
// most common case - inside the image, not on the frist nor last row/column
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x)*(1-frac.y),mp);
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x *(1-frac.y),mp);
|
||||
++loc.y();
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x)* frac.y ,mp);
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x * frac.y ,mp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// on the last row, but not the bottom-left nor bottom-right corner pixel
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x) ,mp);
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x ,mp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p0.y == -1)
|
||||
{
|
||||
// the top-right corner pixel
|
||||
++loc.y();
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, 1 ,mp);
|
||||
}
|
||||
else if (p0.y+1<src.height())
|
||||
{
|
||||
// on the last column, but not the top-right nor bottom-right corner pixel
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.y),mp);
|
||||
++loc.y();
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, frac.y ,mp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the bottom-right corner pixel
|
||||
detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, 1 ,mp);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert from floating point average value to the source type
|
||||
SrcP src_result;
|
||||
cast_pixel(mp,src_result);
|
||||
|
||||
color_convert(src_result, result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}} // namespace boost::gil
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user