fast_gaussian_coefficient.hh

00001 // Copyright (C) 2001, 2002, 2003, 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, 59 Temple Place - Suite 330, Boston,
00016 // MA 02111-1307, 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 #ifndef OLENA_CONVOL_FAST_GAUSSIAN_COEFFICIENT_H__
00029 # define OLENA_CONVOL_FAST_GAUSSIAN_COEFFICIENT_H__
00030 
00031 //
00032 // Gaussian filter implementation from
00033 // "Recursively implementing the gaussian and its derivatives"
00034 // Deriche 93 INRIA REPORT
00035 //
00036 
00043 
00044 
00045 # include <ntg/core/predecls.hh>
00046 # include <vector>
00047 
00048 namespace oln {
00049   namespace convol {
00050     namespace fast {
00051       namespace internal {
00052 
00057         template < class FloatT >
00058         struct recursivefilter_coef_
00059         {
00060           enum FilterType { DericheGaussian,
00061                             DericheGaussianFirstDerivative,
00062                             DericheGaussianSecondDerivative };
00063 
00067           recursivefilter_coef_(FloatT a0, FloatT a1,
00068                                FloatT b0, FloatT b1,
00069                                FloatT c0, FloatT c1,
00070                                FloatT w0, FloatT w1,
00071                                ntg::float_d s, FilterType filter_type);
00072           std::vector<FloatT>   n, d, nm, dm;
00073           FloatT                sumA, sumC;
00074         };
00075 
00076         /*
00077         ** Define out of the struct so the compiler don't even attempt
00078         ** to inline this.
00079         */
00080         template < class FloatT >
00081         recursivefilter_coef_<FloatT>
00082 	::recursivefilter_coef_(FloatT a0, FloatT a1,
00083                                FloatT b0, FloatT b1,
00084                                FloatT c0, FloatT c1,
00085                                FloatT w0, FloatT w1,
00086                                ntg::float_d s, FilterType filter_type)
00087         {
00088           n.reserve(5);
00089           d.reserve(5);
00090           nm.reserve(5);
00091           dm.reserve(5);
00092 
00093           b0 /= s;
00094           b1 /= s;
00095           w0 /= s;
00096           w1 /= s;
00097 
00098           FloatT sin0   = sin(w0);
00099           FloatT sin1   = sin(w1);
00100           FloatT cos0   = cos(w0);
00101           FloatT cos1   = cos(w1);
00102 
00103           switch (filter_type) {
00104 
00105           case DericheGaussian :
00106             {
00107               sumA  =
00108                 (2.0 * a1 * exp( b0 ) * cos0 * cos0 - a0 * sin0 * exp( 2.0 * b0 )
00109                  + a0 * sin0 - 2.0 * a1 * exp( b0 )) /
00110                 (( 2.0 * cos0 * exp( b0 ) - exp( 2.0 * b0 ) - 1 ) * sin0);
00111 
00112               sumC  =
00113                 (2.0 * c1 * exp( b1 ) * cos1 * cos1 - c0 * sin1 * exp( 2.0 * b1 )
00114                  + c0 * sin1 - 2.0 * c1 * exp( b1 ))
00115                 / (( 2.0 * cos1 * exp( b1 ) - exp( 2.0 * b1 ) - 1 ) * sin1);
00116               break;
00117             }
00118 
00119           case DericheGaussianFirstDerivative :
00120             {
00121               sumA  = -2.f *
00122                 (a0 * cos0 - a1 * sin0 + a1 * sin0 * exp( 2.0 * b0 )
00123                  + a0 * cos0 * exp( 2.0 * b0 ) - 2.0 * a0 * exp( b0 ))
00124                 * exp( b0 )
00125                 / (exp( 4.0 * b0 ) - 4.0 * cos0 * exp( 3.0 * b0 )
00126                    + 2.0 * exp( 2.0 * b0 ) + 4.0 * cos0 * cos0 * exp( 2.0 * b0 )
00127                    + 1.0 - 4.0 * cos0 * exp( b0 ));
00128               sumC  = - 2.f *
00129                 (c0 * cos1 - c1 * sin1 + c1 * sin1 * exp( 2.0 * b1 )
00130                  + c0 * cos1 * exp( 2.0 * b1 ) - 2.0 * c0 * exp( b1 ))
00131                 * exp( b1 ) /
00132                 (exp( 4.0 * b1 ) - 4.0 * cos1 * exp( 3.0 * b1 )
00133                  + 2.0 * exp( 2.0 * b1 ) + 4.0 * cos1 * cos1 * exp( 2.0 * b1 )
00134                  + 1.0 - 4.0 * cos1 * exp( b1 ));
00135               break;
00136             }
00137 
00138           case DericheGaussianSecondDerivative :
00139             {
00140               FloatT aux;
00141               aux   =
00142                 12.0 * cos0 * exp( 3.0 * b0 ) - 3.0 * exp( 2.0 * b0 )
00143                 + 8.0 * cos0 * cos0 * cos0 * exp( 3.0 * b0 ) - 12.0 * cos0 * cos0 *
00144                 exp( 4.0 * b0 )
00145                 - (3.0 * exp( 4.0 * b0 ))
00146                 + 6.0 * cos0 * exp( 5.0 * b0 ) -  exp( 6.0 * b0 ) + 6.0 * cos0 * exp
00147                 ( b0 )
00148                 - ( 1.0 + 12.0 * cos0 * cos0 * exp( 2.0 * b0 ) );
00149               sumA  =
00150                 4.0 * a0 * sin0 * exp( 3.0 * b0 ) + a1 * cos0 * cos0 * exp( 4.0 * b0 )
00151                 - ( 4.0 * a0 * sin0 * exp( b0 ) + 6.0 * a1 * cos0 * cos0 * exp( 2.0 * b0 ) )
00152                 + 2.0 * a1 * cos0 * cos0 * cos0 * exp( b0 ) - 2.0 * a1 * cos0 * exp(b0)
00153                 + 2.0 * a1 * cos0 * cos0 * cos0 * exp( 3.0 * b0 ) - 2.0 * a1 * cos0
00154                 * exp( 3.0 * b0 )
00155                 + a1 * cos0 * cos0 - a1 * exp( 4.0 * b0 )
00156                 + 2.0 * a0 * sin0 * cos0 * cos0 * exp( b0 ) - 2.0 * a0 * sin0 * cos0
00157                 * cos0 * exp( 3.0 * b0 )
00158                 - ( a0 * sin0 * cos0 * exp( 4.0 * b0 ) + a1 )
00159                 + 6.0 * a1 * exp( 2.0 * b0 ) + a0 * cos0 * sin0
00160                 * 2.0 * exp( b0 ) / ( aux * sin0 );
00161               aux   =
00162                 12.0 * cos1 * exp( 3.0 * b1 ) - 3.0 * exp( 2.0 * b1 )
00163                 + 8.0 * cos1 * cos1 * cos1 * exp( 3.0 * b1 ) - 12.0 * cos1 * cos1 *
00164                 exp( 4.0 * b1 )
00165                 - 3.0 * exp( 4.0 * b1 )
00166                 + 6.0 * cos1 * exp( 5.0 * b1 ) -  exp( 6.0 * b1 ) + 6.0 * cos1 * exp
00167                 ( b1 )
00168                 - ( 1.0 + 12.0 * cos1 * cos1 * exp( 2.0 * b1 ) );
00169               sumC  = 4.0 * c0 * sin1 * exp( 3.0 * b1 ) + c1 * cos1 * cos1 * exp( 4.0 * b1 )
00170                 - ( 4.0 * c0 * sin1 * exp( b1 ) + 6.0 * c1 * cos1 * cos1 * exp( 2.0 * b1 ) )
00171                 + 2.0 * c1 * cos1 * cos1 * cos1 * exp( b1 ) - 2.0 * c1 * cos1 * exp( b1 )
00172                 + 2.0 * c1 * cos1 * cos1 * cos1 * exp( 3.0 * b1 ) - 2.0 * c1 * cos1
00173                 * exp( 3.0 * b1 )
00174                 + c1 * cos1 * cos1 - c1 * exp( 4.0 * b1 )
00175                 + 2.0 * c0 * sin1 * cos1 * cos1 * exp( b1 ) - 2.0 * c0 * sin1 * cos1
00176                 * cos1 * exp( 3.0 * b1 )
00177                 - ( c0 * sin1 * cos1 * exp( 4.0 * b1 ) + c1 )
00178                 + 6.0 * c1 * exp( 2.0 * b1 ) + c0 * cos1 * sin1
00179                 * 2.0 * exp( b1 ) / ( aux * sin1 );
00180               sumA /= 2;
00181               sumC /= 2;
00182               break;
00183             }
00184           }
00185 
00186           a0 /= (sumA + sumC);
00187           a1 /= (sumA + sumC);
00188           c0 /= (sumA + sumC);
00189           c1 /= (sumA + sumC);
00190 
00191           n[3] =
00192             exp( -b1 - 2*b0 ) * (c1 * sin1 - cos1 * c0) +
00193             exp( -b0 - 2*b1 ) * (a1 * sin0 - cos0 * a0);
00194           n[2] =
00195             2 * exp(-b0 - b1) * ((a0 + c0) * cos1 * cos0 -
00196                                  cos1 * a1 * sin0 -
00197                                  cos0 * c1 * sin1) +
00198             c0 * exp(-2 * b0) + a0 * exp(-2 * b1);
00199           n[1] =
00200             exp(-b1) * (c1 * sin1 - (c0 + 2*a0) * cos1) +
00201             exp(-b0) * (a1 * sin0 - (2*c0 + a0) * cos0);
00202           n[0] =
00203             a0 + c0;
00204 
00205           d[4] = exp(-2 * b0 - 2 * b1);
00206           d[3] =
00207             -2 * cos0 * exp(-b0 - 2*b1) -
00208             2 * cos1 * exp(-b1 - 2*b0);
00209           d[2] =
00210             4 * cos1 * cos0 * exp(-b0 - b1) +
00211             exp(-2*b1) + exp(-2*b0);
00212           d[1] =
00213             -2*exp(-b1) * cos1 - 2 * exp(-b0) * cos0;
00214 
00215           switch (filter_type) {
00216           case DericheGaussian :
00217           case DericheGaussianSecondDerivative :
00218             {
00219               for (unsigned i = 1; i <= 3; ++i)
00220                 {
00221                   dm[i] = d[i];
00222                   nm[i] = n[i] - d[i] * n[0];
00223                 }
00224               dm[4] = d[4];
00225               nm[4] = -d[4] * n[0];
00226               break;
00227             }
00228           case DericheGaussianFirstDerivative :
00229             {
00230               for (unsigned i = 1; i <= 3; ++i)
00231                 {
00232                   dm[i] = d[i];
00233                   nm[i] = - (n[i] - d[i] * n[0]);
00234                 }
00235               dm[4] = d[4];
00236               nm[4] = d[4] * n[0];
00237               break;
00238             }
00239           }
00240         }
00241 
00242 
00243       } // internal
00244     } // fast
00245   } // convol
00246 } // oln
00247 
00248 
00249 #endif // OLENA_CONVOL_FAST_GAUSSIAN_COEFFICIENT_H__

Generated on Thu Apr 15 20:13:09 2004 for Olena by doxygen 1.3.6-20040222