Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

MakeGaussian1d.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Array_MakeGaussian1d_h
00002 #define Impala_Core_Array_MakeGaussian1d_h
00003 
00004 //#include "Data/Basis/CxMath.h"
00005 #include "Core/Array/Arrays.h"
00006 
00007 namespace Impala
00008 {
00009 namespace Core
00010 {
00011 namespace Array
00012 {
00013 
00014 
00015 // recursive Gaussian derivative: 
00016 // deriv(x,n) = -(n-1)/sigma^2 * deriv(x,n-2) - x/sigma^2 * deriv(x,n-1)
00017 // with Gauss = deriv(x,0) = b exp(a x^2)
00018 
00019 static inline double
00020 Gauss(const double x, const double sigma)
00021 {
00022     // normalization to sum=1. is performed later
00023     return exp(-0.5 * x * x / (sigma*sigma));
00024 }
00025 
00026 static inline double
00027 Hermite(const double x, const double H0, const double sigma, const int order)
00028 {
00029     if (!order)
00030         return H0;
00031 
00032     double a = 1./(sigma*sigma);
00033     double ax = a*x;
00034     double Hnmin1 = H0;
00035     double Hn = -ax*H0;
00036 
00037     int n;
00038     for( n = 2; n <= order; n++ ) {
00039         double Hnmin2 = Hnmin1;
00040         Hnmin1 = Hn;
00041         Hn = a*(1-n)*Hnmin2 - ax*Hnmin1;
00042     }
00043 
00044     return (order%2) ? -Hn : Hn;
00045 }
00046 
00047 static inline int
00048 filterWidth(double sigma, int deri, double acc, int maxlen)
00049 {
00050     double     acc2;
00051     int        fsize;
00052 
00053     acc2 = 1.0 - (1.0 - acc)/2.0;
00054 
00055     fsize = 2*int(acc*sigma+0.5)+1;
00056 
00057     /*  filter kernel is always odd sized, so if maxlen is even 
00058      *  subtract one.
00059      */
00060     if ( !(maxlen%2) )
00061         maxlen--; 
00062     if (fsize > maxlen)
00063         fsize = maxlen;
00064 
00065     return fsize;
00066 }
00067 
00068 static inline double*
00069 makeFilter(double sigma, int deri, double acc, int fsize, int maxfsize)
00070 {
00071     double* filter = new double[fsize];
00072 
00073     fsize = fsize/2; /* adjust to one side ,don't count the centre */
00074     double* center = filter + fsize;
00075 
00076     /* calc filter */
00077     int i;
00078     double sum = Gauss(0.0, sigma);
00079     center[0] = sum;
00080 
00081     for (i=1; i<=fsize; i++) {
00082         double val = Gauss(i, sigma);
00083         sum += val+val;
00084         center[i] = val;
00085         center[-i] = val;
00086     }
00087 
00088     /* normalize to sum=1.0 */
00089     for (i=-fsize; i<=fsize; i++)
00090         center[i] /= sum;
00091 
00092     /* replace by Hermite polynomial of order deri */
00093     if (deri > 0)
00094         for (i=-fsize; i<=fsize; i++)
00095             center[i] = Hermite(i, center[i], sigma, deri);
00096 
00097     fsize = fsize * 2 + 1; /* expand to 2-sided width */
00098     return filter;
00099 }
00100 
00103 inline Array2dScalarReal64*
00104 MakeGaussian1d(double sigma, int deri, double acc, int maxfsize, int fsize = 0)
00105 {
00106     if (fsize < 1) { /* determine filter size if not specified */
00107         fsize = filterWidth(sigma, deri, acc, maxfsize);
00108     }
00109 
00110     double* fData = makeFilter(sigma, deri, acc, fsize, maxfsize);
00111     return ArrayCreate<Array2dScalarReal64>(fsize, 1, 0, 0, fData);
00112 }
00113 
00114 } // namespace Array
00115 } // namespace Core
00116 } // namespace Impala
00117 
00118 #endif

Generated on Fri Mar 19 09:30:48 2010 for ImpalaSrc by  doxygen 1.5.1