Turi Create  4.0
sampler.hpp
Go to the documentation of this file.
1 /* Copyright © 2017 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 /*
7  Copyright 2005-2007 Adobe Systems Incorporated
8  Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
9  or a copy at http://opensource.adobe.com/licenses.html)
10 */
11 
12 /*************************************************************************************************/
13 
14 #ifndef GIL_SAMPLER_HPP
15 #define GIL_SAMPLER_HPP
16 
17 #include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
19 
20 ////////////////////////////////////////////////////////////////////////////////////////
21 /// \file
22 /// \brief Nearest-neighbor and bilinear image samplers.
23 /// NOTE: The code is for example use only. It is not optimized for performance
24 /// \author Lubomir Bourdev and Hailin Jin \n
25 /// Adobe Systems Incorporated
26 /// \date 2005-2007 \n October 30, 2006
27 ///
28 ////////////////////////////////////////////////////////////////////////////////////////
29 
30 namespace boost { namespace gil {
31 
32 ///////////////////////////////////////////////////////////////////////////
33 ////
34 //// resample_pixels: set each pixel in the destination view as the result of a sampling function over the transformed coordinates of the source view
35 ////
36 ///////////////////////////////////////////////////////////////////////////
37 /*
38 template <typename Sampler>
39 concept SamplerConcept {
40  template <typename DstP, // Models PixelConcept
41  typename SrcView, // Models RandomAccessNDImageViewConcept
42  typename S_COORDS> // Models PointNDConcept, where S_COORDS::num_dimensions == SrcView::num_dimensions
43  bool sample(const Sampler& s, const SrcView& src, const S_COORDS& p, DstP result);
44 };
45 */
46 
47 /// \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
48 /// \ingroup ImageAlgorithms
50 
51 template <typename DstP, typename SrcView, typename F>
52 bool sample(nearest_neighbor_sampler, const SrcView& src, const point2<F>& p, DstP& result) {
53  point2<int> center(static_cast<int>(iround(p).x), static_cast<int>(iround(p).y));
54  if (center.x>=0 && center.y>=0 && center.x<src.width() && center.y<src.height()) {
55  result=src(center.x,center.y);
56  return true;
57  }
58  return false;
59 }
60 
61 struct cast_channel_fn {
62  template <typename SrcChannel, typename DstChannel>
63  void operator()(const SrcChannel& src, DstChannel& dst) {
64  typedef typename channel_traits<DstChannel>::value_type dst_value_t;
65  dst = dst_value_t(src);
66  }
67 };
68 
69 template <typename SrcPixel, typename DstPixel>
70 void cast_pixel(const SrcPixel& src, DstPixel& dst) {
71  static_for_each(src,dst,cast_channel_fn());
72 }
73 
74 namespace detail {
75 
76 template <typename Weight>
77 struct add_dst_mul_src_channel {
78  Weight _w;
79  add_dst_mul_src_channel(Weight w) : _w(w) {}
80 
81  template <typename SrcChannel, typename DstChannel>
82  void operator()(const SrcChannel& src, DstChannel& dst) const {
83  dst += DstChannel(src*_w);
84  }
85 };
86 
87 // dst += DST_TYPE(src * w)
88 template <typename SrcP,typename Weight,typename DstP>
89 struct add_dst_mul_src {
90  void operator()(const SrcP& src, Weight weight, DstP& dst) const {
91  static_for_each(src,dst, add_dst_mul_src_channel<Weight>(weight));
92 // pixel_assigns_t<DstP,DstP&>()(
93 // pixel_plus_t<DstP,DstP,DstP>()(
94 // pixel_multiplies_scalar_t<SrcP,Weight,DstP>()(src,weight),
95 // dst),
96 // dst);
97  }
98 };
99 } // namespace detail
100 
101 /// \brief A sampler that sets the destination pixel as the bilinear interpolation of the four closest pixels from the source.
102 /// If outside the bounds, it doesn't change the destination
103 /// \ingroup ImageAlgorithms
105 
106 template <typename DstP, typename SrcView, typename F>
107 bool sample(bilinear_sampler, const SrcView& src, const point2<F>& p, DstP& result) {
108  typedef typename SrcView::value_type SrcP;
109  point2<std::ptrdiff_t> p0(ifloor(p)); // the closest integer coordinate top left from p
110  point2<F> frac(p.x-p0.x, p.y-p0.y);
111  if (p0.x < 0 || p0.y < 0 || p0.x>=src.width() || p0.y>=src.height()) return false;
112 
113  pixel<F,devicen_layout_t<num_channels<SrcView>::value> > mp(0); // suboptimal
114  typename SrcView::xy_locator loc=src.xy_at(p0.x,p0.y);
115 
116  if (p0.x+1<src.width()) {
117  if (p0.y+1<src.height()) {
118  // most common case - inside the image, not on the last row or column
119  detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x)*(1-frac.y),mp);
120  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);
121  ++loc.y();
122  detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x)* frac.y ,mp);
123  detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x * frac.y ,mp);
124  } else {
125  // on the last row, but not the bottom-right corner pixel
126  detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.x),mp);
127  detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(loc.x()[1], frac.x ,mp);
128  }
129  } else {
130  if (p0.y+1<src.height()) {
131  // on the last column, but not the bottom-right corner pixel
132  detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, (1-frac.y),mp);
133  ++loc.y();
134  detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc, frac.y ,mp);
135  } else {
136  // the bottom-right corner pixel
137  detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()(*loc,1,mp);
138  }
139  }
140 
141  // Convert from floating point average value to the source type
142  SrcP src_result;
143  cast_pixel(mp,src_result);
144 
145  color_convert(src_result, result);
146  return true;
147 }
148 
149 } } // namespace boost::gil
150 
151 #endif
A sampler that sets the destination pixel as the bilinear interpolation of the four closest pixels fr...
Definition: sampler.hpp:104
Structures for pixel-wise numeric operations /.
A sampler that sets the destination pixel to the closest one in the source. If outside the bounds...
Definition: sampler.hpp:49