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