$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
bilinear.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
2 // (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_FUN_X2V_BILINEAR_HH
28 # define MLN_FUN_X2V_BILINEAR_HH
29 
30 # include <mln/core/image/image2d.hh>
31 # include <mln/core/concept/function.hh>
32 # include <mln/fun/internal/selector.hh>
33 # include <mln/convert/to.hh>
34 # include <mln/algebra/vec.hh>
35 
39 
40 namespace mln
41 {
42 
43  namespace fun
44  {
45 
46  namespace x2v
47  {
48 
51  template < typename I >
52  struct bilinear
53  : public fun::internal::selector_<const algebra::vec<3,float>,
54  // 3,float is a dummy parameter (real is n,T)
55  mln_value(I), bilinear<I> >::ret
56  {
57  typedef mln_value(I) result;
58 
59  bilinear(const I& ima);
60 
62  template <typename T>
63  mln_value(I)
64  operator()(const algebra::vec<2,T>& v) const;
65 
67  template <typename T>
68  mln_value(I)
69  operator()(const algebra::vec<3,T>& v) const;
70 
71  const I& ima;
72  };
73 
74 
75 # ifndef MLN_INCLUDE_ONLY
76 
77  template <typename I>
78  bilinear<I>::bilinear(const I& ima) : ima(ima)
79  {
80  mlc_or(mlc_bool(I::psite::dim == 2), mlc_bool(I::psite::dim == 3))::check();
81  }
82 
83  template <typename I>
84  template <typename T>
85  mln_value(I)
86  bilinear<I>::operator()(const algebra::vec<2,T>& v) const
87  {
88  typedef mln_sum(mln_value(I)) vsum;
89 
90  // q12----r2----q22
91  // | | |
92  // | x |
93  // | | |
94  // q11----r1----q21
95 
96  // looking for img(P(x,y))
97  double x = v[0];
98  double y = v[1];
99 
100  double x1 = std::floor(v[0]);
101  double x2 = std::floor(v[0]) + 1;
102  double y1 = std::floor(v[1]);
103  double y2 = std::floor(v[1]) + 1;
104 
105  //Following access are supposed valid.
106  vsum q11 = ima(point2d(static_cast<unsigned>(x1), static_cast<unsigned>(y1)));
107  vsum q12 = ima(point2d(static_cast<unsigned>(x1), static_cast<unsigned>(y2)));
108  vsum q21 = ima(point2d(static_cast<unsigned>(x2), static_cast<unsigned>(y1)));
109  vsum q22 = ima(point2d(static_cast<unsigned>(x2), static_cast<unsigned>(y2)));
110 
111  double x2_x1 = x2 - x1;
112  double y2_y1 = y2 - y1;
113 
114  // linear interpolation #1
115  vsum img_r1 = q11 * (x2 - x) / (x2_x1) +
116  q21 * (x - x1) / (x2_x1);
117 
118  // linear interpolation #2
119  vsum img_r2 = q12 * (x2 - x) / (x2_x1) + q22 * (x - x1) / (x2_x1);
120 
121  // interpolating in y direction
122  vsum res = (img_r1 * (y2 - y) / (y2_y1)
123  + img_r2 * (y - y1) / (y2_y1));
124 
125  return convert::to<mln_value(I)>(res);
126  }
127 
128 
129  template <typename I>
130  template <typename T>
131  mln_value(I)
132  bilinear<I>::operator()(const algebra::vec<3,T>& v) const
133  {
134  typedef mln_sum(mln_value(I)) vsum;
135 
136  // q12----r2----q22
137  // | | |
138  // | x |
139  // | | |
140  // q11----r1----q21
141 
142  double x = v[0];
143  double y = v[1];
144 
145  double x1 = std::floor(x);
146  double x2 = std::floor(x) + 1;
147  double y1 = std::floor(y);
148  double y2 = std::floor(y) + 1;
149  def::coord z = math::round<float>(v[3]);
150 
151  //Following access are supposed valid.
152  vsum q11 = ima(point3d(z, static_cast<unsigned>(x1), static_cast<unsigned>(y1)));
153  vsum q12 = ima(point3d(z, static_cast<unsigned>(x1), static_cast<unsigned>(y2)));
154  vsum q21 = ima(point3d(z, static_cast<unsigned>(x2), static_cast<unsigned>(y1)));
155  vsum q22 = ima(point3d(z, static_cast<unsigned>(x2), static_cast<unsigned>(y2)));
156 
157  double x2_x1 = x2 - x1;
158  double y2_y1 = y2 - y1;
159 
160  // linear interpolation #1
161  vsum img_r1 = q11 * (x2 - x) / (x2_x1) +
162  q21 * (x - x1) / (x2_x1);
163 
164  // linear interpolation #2
165  vsum img_r2 = q12 * (x2 - x) / (x2_x1) + q22 * (x - x1) / (x2_x1);
166 
167  // interpolating in y direction
168  vsum res = (img_r1 * (y2 - y) / (y2_y1)
169  + img_r2 * (y - y1) / (y2_y1));
170 
171  return convert::to<mln_value(I)>(res);
172  }
173 
174 
175 # endif // ! MLN_INCLUDE_ONLY
176 
177  } // end of namespace mln::fun::x2v
178 
179  } // end of namespace mln::fun
180 
181 } // end of namespace mln
182 
183 
184 #endif // ! MLN_FUN_X2V_BILINEAR_HH