Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory 00002 // (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 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 // 3,float is a dummy parameter (real is n,T) 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 // q12----r2----q22 00091 // | | | 00092 // | x | 00093 // | | | 00094 // q11----r1----q21 00095 00096 // looking for img(P(x,y)) 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 //Following access are supposed valid. 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 // linear interpolation #1 00115 vsum img_r1 = q11 * (x2 - x) / (x2_x1) + 00116 q21 * (x - x1) / (x2_x1); 00117 00118 // linear interpolation #2 00119 vsum img_r2 = q12 * (x2 - x) / (x2_x1) + q22 * (x - x1) / (x2_x1); 00120 00121 // interpolating in y direction 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 // q12----r2----q22 00137 // | | | 00138 // | x | 00139 // | | | 00140 // q11----r1----q21 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 //Following access are supposed valid. 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 // linear interpolation #1 00161 vsum img_r1 = q11 * (x2 - x) / (x2_x1) + 00162 q21 * (x - x1) / (x2_x1); 00163 00164 // linear interpolation #2 00165 vsum img_r2 = q12 * (x2 - x) / (x2_x1) + q22 * (x - x1) / (x2_x1); 00166 00167 // interpolating in y direction 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 } // end of namespace mln::fun::x2v 00178 00179 } // end of namespace mln::fun 00180 00181 } // end of namespace mln 00182 00183 00184 #endif // ! MLN_FUN_X2V_BILINEAR_HH