/usr/include/boost/gil/extension/numeric
Edit: /usr/include/boost/gil/extension/numeric/sampler.hpp (7256B)
//
// 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
#include
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
concept SamplerConcept {
template // 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
bool sample(nearest_neighbor_sampler, SrcView const& src, point 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
void operator()(const SrcChannel& src, DstChannel& dst) {
using dst_value_t = typename channel_traits::value_type;
dst = dst_value_t(src);
}
};
template
void cast_pixel(const SrcPixel& src, DstPixel& dst) {
static_for_each(src,dst,cast_channel_fn());
}
namespace detail {
template
struct add_dst_mul_src_channel {
Weight _w;
add_dst_mul_src_channel(Weight w) : _w(w) {}
template
void operator()(const SrcChannel& src, DstChannel& dst) const {
dst += DstChannel(src*_w);
}
};
// dst += DST_TYPE(src * w)
template
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));
// pixel_assigns_t()(
// pixel_plus_t()(
// pixel_multiplies_scalar_t()(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
bool sample(bilinear_sampler, SrcView const& src, point 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 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::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::value> > >()(loc.x()[1], 1 ,mp);
}
else if (p0.y+1::value> > >()(loc.x()[1], (1-frac.y),mp);
++loc.y();
detail::add_dst_mul_src::value> > >()(loc.x()[1], frac.y ,mp);
}
else
{
// the bottom-left corner pixel
detail::add_dst_mul_src::value> > >()(loc.x()[1], 1 ,mp);
}
}
else if (p0.x+1::value> > >()(*loc, (1-frac.x) ,mp);
detail::add_dst_mul_src::value> > >()(loc.x()[1], frac.x ,mp);
}
else if (p0.y+1::value> > >()(*loc, (1-frac.x)*(1-frac.y),mp);
detail::add_dst_mul_src::value> > >()(loc.x()[1], frac.x *(1-frac.y),mp);
++loc.y();
detail::add_dst_mul_src::value> > >()(*loc, (1-frac.x)* frac.y ,mp);
detail::add_dst_mul_src::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::value> > >()(*loc, (1-frac.x) ,mp);
detail::add_dst_mul_src::value> > >()(loc.x()[1], frac.x ,mp);
}
}
else
{
if (p0.y == -1)
{
// the top-right corner pixel
++loc.y();
detail::add_dst_mul_src::value> > >()(*loc, 1 ,mp);
}
else if (p0.y+1::value> > >()(*loc, (1-frac.y),mp);
++loc.y();
detail::add_dst_mul_src::value> > >()(*loc, frac.y ,mp);
}
else
{
// the bottom-right corner pixel
detail::add_dst_mul_src::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