• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

bilinear.hh

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

Generated on Thu Sep 8 2011 18:31:30 for Milena (Olena) by  doxygen 1.7.1