shapelets.hh

00001 // Copyright (C) 2004  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016 // Boston, MA 02110-1301, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library 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
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
00027 
00028 
00029 #ifndef OLENA_TRANSFORMS_SHAPELETS_HH
00030 # define OLENA_TRANSFORMS_SHAPELETS_HH
00031 
00032 #include <ntg/int.hh>
00033 #include <oln/basics2d.hh>
00034 
00035 
00036 #include <oln/core/image.hh>
00037 #include <oln/core/point1d.hh>
00038 #include <oln/core/point2d.hh>
00039 #include <oln/level/fill.hh>
00040 #include <vector>
00041 #include <bits/stl_function.h>
00042 
00043 namespace oln
00044 {
00045   namespace internal
00046   {
00047     template <class T>
00048     struct hermite : public std::binary_function<T, int, T>
00049     {
00050       T operator()(unsigned n, T x)
00051       {
00052         T       a;
00053         T       b;
00054         T       c;
00055 
00056         if (n == 0)
00057           return 1.;
00058         if (n == 1)
00059           return 2. * x;
00060         a = 1.;
00061         b = 2. * x;
00062         for (unsigned i = 2; i <= n; i++)
00063           {
00064             c = b;
00065             b = 2. * x * b - 2. * T(i - 1) * a;
00066             a = c;
00067           }
00068         return b;
00069       }
00070     };
00071 
00072     template <class T>
00073     struct fact : public std::unary_function<T, T>
00074     {
00075 
00076 
00077 
00078       T operator() (T n)
00079       {
00080         precondition(n >= 0);
00081         T res = 1;
00082 
00083         while (n > 0)
00084           {
00085             res *= n;
00086             n--;
00087           }
00088         return res;
00089       }
00090     };
00091 
00092     template <class T>
00093     struct shapelets_beta : public std::binary_function<T, int, T>
00094     {
00095       T operator()(int n, T x)
00096       {
00097         assert(n >= 0);
00098         const double c = sqrt(pow(2.0, n) * sqrt(M_PI) * fact<T>()(n));
00099 
00100         return hermite<T>()(n, x) * exp(x * x / -2.0) / c;
00101       }
00102     };
00103 
00104     template <unsigned Dim, class T>
00105     struct shapelets_basis
00106     {
00107     };
00108 
00109     template <class T>
00110     struct shapelets_basis<1, T>
00111     {
00112       T operator() (int n, point1d p, T b)
00113       {
00114         assert(n >= 0 && b >= 0);
00115         return shapelets_beta<T>(n, p.col() / b) / sqrt(b);
00116       }
00117     };
00118 
00119     template <class T>
00120     struct shapelets_basis<2, T>
00121     {
00122       T operator() (int m, int n, T x, T y, T b)
00123       {
00124         assert(m >= 0 && n >= 0 && b >= 0);
00125         return shapelets_beta<T>()(m, x / b) * shapelets_beta<T>()(n, y / b) / b;
00126       }
00127     };
00128 
00129 
00130     //FIXME: ima should be non_vectorial
00131     template <class I>
00132     std::vector<double>
00133     shapelets(const oln::abstract::image_with_dim<2, I>& ima,
00134                          int m, int n,
00135                          double b)
00136     {
00137       assert(m >= 0 && n >= 0 && b >= 0);
00138       shapelets_basis<2, double> func;
00139 
00140       // Center of the image
00141       const int col = ima.ncols() / 2;
00142       const int row = ima.nrows() / 2;
00143 
00144       std::vector<double> res(m * n);
00145 
00146       // For all vector in the base of shapelets
00147       for (int k = 0; k < m; k++)
00148         for (int l = 0; l < n; l++)
00149           // res[k * n + l] = scalar product of the image and the function
00150           {
00151             double s = 0.0;
00152 
00153             oln_iter_type(I) it(ima);
00154             for_all(it)
00155               {
00156                 s += (ima[it]) * //ntg_max_val(oln_value_type(I)) - ima[it]) *
00157                   func(k, l, double(it.row() - row), double(it.col() - col), b);
00158               }
00159             res[k * n + l] = s;
00160             //      std::cout << k << " - " << l << " = " << s << std::endl;
00161 
00162           }
00163       return res;
00164     }
00165 
00166 
00167     template <class D>
00168     image2d<D>
00169     unshapelets(const std::vector<double> &vec,
00170                 int m, int n, double b,
00171                 coord nrows, coord ncols)
00172     {
00173       precondition(nrows >= 1 && ncols >= 1  &&
00174                    m >= 0 && n >= 0 && b >= 0);
00175 
00176 
00177       typedef image2d<double> tmp_type;
00178       tmp_type resf(oln::image2d_size(nrows, ncols, 0));
00179 
00180       oln_iter_type(tmp_type) it(resf);
00181 
00182       oln::level::fill(resf, ntg_min_val(D));
00183       // For each vector
00184       for (int k = 0; k < m; k++)
00185         for (int l = 0; l < n; l++)
00186           // Add the value at the point
00187           {
00188             if (vec[k * n + l] * vec[k * n + l] > 20000)
00189               {
00190                 for_all(it)
00191                   resf[it] += vec[k * n + l] *
00192                   shapelets_basis<2, double>()(k, l, double(it.row() - nrows / 2), double(it.col() - ncols / 2), b);
00193                 std::cout << k << " - " << l << " = " << vec[k * n + l] << std::endl;
00194               }
00195           }
00196 
00197       image2d<D> res(oln::image2d_size(nrows, ncols, 0));
00198 
00199       for_all(it)
00200         {
00201           if ( !(resf[it] >= 0 && resf[it] <= 255))
00202             {
00203               std::cout << "- ";
00204               std::cout << "err:" << resf[it];
00205               //            min = (resf[it] < min)? resf[it]:min;
00206               //            max = (resf[it] >max)? resf[it]:max;
00207               res[it] = resf[it] < 0 ? 0 : ntg_max_val(D);
00208               std::cout << " -" << std::endl;
00209             }
00210           else
00211             res[it] = resf[it];
00212         }
00213       //    std::cout << "min:" << min
00214       //              << " max:" << max << std::endl;
00215       return res;
00216     }
00217 
00218   }
00219 }
00220 
00221 #endif // ! OLENA_TRANSFORMS_SHAPELETS_HH

Generated on Tue Feb 20 20:20:32 2007 for Olena by  doxygen 1.5.1