00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_FUN_X2V_BILINEAR_HH
00027 # define MLN_FUN_X2V_BILINEAR_HH
00028
00029 # include <mln/core/image/image2d.hh>
00030 # include <mln/core/concept/function.hh>
00031 # include <mln/fun/internal/selector.hh>
00032 # include <mln/convert/to.hh>
00033 # include <mln/algebra/vec.hh>
00034
00038
00039 namespace mln
00040 {
00041
00042 namespace fun
00043 {
00044
00045 namespace x2v
00046 {
00047
00050 template < typename I >
00051 struct bilinear
00052 : public fun::internal::selector_<const algebra::vec<3,float>,
00053
00054 mln_value(I), bilinear<I> >::ret
00055 {
00056 typedef mln_value(I) result;
00057
00058 bilinear(const I& ima);
00059
00061 template <typename T>
00062 mln_value(I)
00063 operator()(const algebra::vec<2,T>& v) const;
00064
00066 template <typename T>
00067 mln_value(I)
00068 operator()(const algebra::vec<3,T>& v) const;
00069
00070 const I& ima;
00071 };
00072
00073
00074 # ifndef MLN_INCLUDE_ONLY
00075
00076 template <typename I>
00077 bilinear<I>::bilinear(const I& ima) : ima(ima)
00078 {
00079 mlc_or(mlc_bool(I::psite::dim == 2), mlc_bool(I::psite::dim == 3))::check();
00080 }
00081
00082 template <typename I>
00083 template <typename T>
00084 mln_value(I)
00085 bilinear<I>::operator()(const algebra::vec<2,T>& v) const
00086 {
00087 typedef mln_sum(mln_value(I)) vsum;
00088
00089
00090
00091
00092
00093
00094
00095
00096 double x = v[0];
00097 double y = v[1];
00098
00099 double x1 = std::floor(v[0]);
00100 double x2 = std::floor(v[0]) + 1;
00101 double y1 = std::floor(v[1]);
00102 double y2 = std::floor(v[1]) + 1;
00103
00104
00105 vsum q11 = ima(point2d(static_cast<unsigned>(x1), static_cast<unsigned>(y1)));
00106 vsum q12 = ima(point2d(static_cast<unsigned>(x1), static_cast<unsigned>(y2)));
00107 vsum q21 = ima(point2d(static_cast<unsigned>(x2), static_cast<unsigned>(y1)));
00108 vsum q22 = ima(point2d(static_cast<unsigned>(x2), static_cast<unsigned>(y2)));
00109
00110 double x2_x1 = x2 - x1;
00111 double y2_y1 = y2 - y1;
00112
00113
00114 vsum img_r1 = q11 * (x2 - x) / (x2_x1) +
00115 q21 * (x - x1) / (x2_x1);
00116
00117
00118 vsum img_r2 = q12 * (x2 - x) / (x2_x1) + q22 * (x - x1) / (x2_x1);
00119
00120
00121 vsum res = (img_r1 * (y2 - y) / (y2_y1)
00122 + img_r2 * (y - y1) / (y2_y1));
00123
00124 return convert::to<mln_value(I)>(res);
00125 }
00126
00127
00128 template <typename I>
00129 template <typename T>
00130 mln_value(I)
00131 bilinear<I>::operator()(const algebra::vec<3,T>& v) const
00132 {
00133 typedef mln_sum(mln_value(I)) vsum;
00134
00135
00136
00137
00138
00139
00140
00141 double x = v[0];
00142 double y = v[1];
00143
00144 double x1 = std::floor(x);
00145 double x2 = std::floor(x) + 1;
00146 double y1 = std::floor(y);
00147 double y2 = std::floor(y) + 1;
00148 def::coord z = math::round<float>()(v[3]);
00149
00150
00151 vsum q11 = ima(point3d(z, static_cast<unsigned>(x1), static_cast<unsigned>(y1)));
00152 vsum q12 = ima(point3d(z, static_cast<unsigned>(x1), static_cast<unsigned>(y2)));
00153 vsum q21 = ima(point3d(z, static_cast<unsigned>(x2), static_cast<unsigned>(y1)));
00154 vsum q22 = ima(point3d(z, static_cast<unsigned>(x2), static_cast<unsigned>(y2)));
00155
00156 double x2_x1 = x2 - x1;
00157 double y2_y1 = y2 - y1;
00158
00159
00160 vsum img_r1 = q11 * (x2 - x) / (x2_x1) +
00161 q21 * (x - x1) / (x2_x1);
00162
00163
00164 vsum img_r2 = q12 * (x2 - x) / (x2_x1) + q22 * (x - x1) / (x2_x1);
00165
00166
00167 vsum res = (img_r1 * (y2 - y) / (y2_y1)
00168 + img_r2 * (y - y1) / (y2_y1));
00169
00170 return convert::to<mln_value(I)>(res);
00171 }
00172
00173
00174 # endif // ! MLN_INCLUDE_ONLY
00175
00176 }
00177
00178 }
00179
00180 }
00181
00182
00183 #endif // ! MLN_FUN_X2V_BILINEAR_HH