contrib/brl/bseg/brip/brip_gaussian_kernel.h
Go to the documentation of this file.
00001 // This is brl/bseg/brip/brip_gaussian_kernel.h
00002 #ifndef brip_gaussian_kernel_h
00003 #define brip_gaussian_kernel_h
00004 //:
00005 // \file
00006 // \brief Gaussian derivative kernels
00007 // \author Amir Tamrakar
00008 // \date 9 Sept 2006
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   <none yet>
00013 // \endverbatim
00014 
00015 #include <brip/brip_kernel.h>
00016 #include <vnl/vnl_math.h>
00017 #include <vcl_vector.h>
00018 
00019 //: Gaussian derivative kernel base class
00020 class brip_gaussian_kernel : public brip_kernel
00021 {
00022  public:
00023   int khs;                     //kernel half size
00024   vcl_vector<double> K_x, K_y; //separated kernels to minimize computation
00025 
00026  protected:
00027   double sigma; ///< operator sigma
00028 
00029  public:
00030   //: constructor given sigma and shifts
00031   brip_gaussian_kernel(double sigma_, double dx_=0.0, double dy_=0.0, double theta_=0.0):
00032     brip_kernel((unsigned)(2*vcl_ceil(4*sigma_)+1), (unsigned)(2*vcl_ceil(4*sigma_)+1), dx_, dy_, theta_),
00033     khs((int) vcl_ceil(4*sigma_)), K_x(2*khs+1, 0.0), K_y(2*khs+1, 0.0), sigma(sigma_)
00034   {
00035     compute_kernel();
00036   }
00037   //: destructor
00038   ~brip_gaussian_kernel(){}
00039 
00040   //: compute the kernel
00041   virtual void compute_kernel(bool /*separated_kernels_only*/=false){}
00042 
00043   //: recompute kernel with given subpixel shifts
00044   virtual void recompute_kernel(double dx_=0.0, double dy_=0.0, double theta_=0.0)
00045   {
00046     dx = dx_;
00047     dy = dy_;
00048     theta = theta_;
00049     compute_kernel();
00050   }
00051 };
00052 
00053 //: Gaussian Left half kernel at the given orientation
00054 //  Note: not separable
00055 class brip_G_Lhalf_kernel : public brip_gaussian_kernel
00056 {
00057  public:
00058   brip_G_Lhalf_kernel(double sigma_, double dx_=0.0, double dy_=0.0, double theta_=0.0): brip_gaussian_kernel(sigma_, dx_, dy_, theta_){}
00059   ~brip_G_Lhalf_kernel(){}
00060 
00061   //: compute the kernel
00062   virtual void compute_kernel(bool /*separated_kernels_only*/=false)
00063   {
00064     double ssq = sigma*sigma;
00065     //double pisig2 = 2*vnl_math::pi*ssq;
00066     double cc = vcl_sqrt(2*vnl_math::pi)*ssq*sigma;
00067 
00068     //not separable
00069     for (int x = -khs; x <= khs; x++){
00070       for (int y = -khs; y <= khs; y++){
00071 
00072         double xx = x* vcl_cos(theta) + y*vcl_sin(theta) - dx;
00073         double yy = x*-vcl_sin(theta) + y*vcl_cos(theta) - dy;
00074 
00075         //only one half is a Gaussian (the other half is zeros)
00076         if (yy>=0)
00077           top_left_[(x+khs)*istep_+ (y+khs)*jstep_] = 0.0;
00078         else
00079           //top_left_[(x+khs)*istep_+ (y+khs)*jstep_] = 2*vcl_exp(-xx*xx/(2*ssq))*vcl_exp(-yy*yy/(2*ssq))/pisig2;
00080           top_left_[(x+khs)*istep_+ (y+khs)*jstep_] = vcl_exp(-xx*xx/(2*ssq))*yy*-vcl_exp(-yy*yy/(2*ssq))/cc;
00081       }
00082     }
00083   }
00084 };
00085 
00086 //: Gaussian Right half kernel at the given orientation
00087 //  Note: not separable
00088 class brip_G_Rhalf_kernel : public brip_gaussian_kernel
00089 {
00090  public:
00091   brip_G_Rhalf_kernel(double sigma_, double dx_=0.0, double dy_=0.0, double theta_=0.0): brip_gaussian_kernel(sigma_, dx_, dy_, theta_){}
00092   ~brip_G_Rhalf_kernel(){}
00093 
00094   //: compute the kernel
00095   virtual void compute_kernel(bool /*separated_kernels_only*/=false)
00096   {
00097     double ssq = sigma*sigma;
00098     //double pisig2 = 2*vnl_math::pi*ssq;
00099     double cc = vcl_sqrt(2*vnl_math::pi)*ssq*sigma;
00100 
00101     //not separable
00102     for (int x = -khs; x <= khs; x++){
00103       for (int y = -khs; y <= khs; y++){
00104 
00105         double xx = x* vcl_cos(theta) + y*vcl_sin(theta) - dx;
00106         double yy = x*-vcl_sin(theta) + y*vcl_cos(theta) - dy;
00107 
00108         //only one half is a Gaussian (the other half is zeros)
00109         if (yy<0)
00110           top_left_[(x+khs)*istep_+ (y+khs)*jstep_] = 0.0;
00111         else
00112           //top_left_[(x+khs)*istep_+ (y+khs)*jstep_] = 2*vcl_exp(-xx*xx/(2*ssq))*vcl_exp(-yy*yy/(2*ssq))/pisig2;
00113           top_left_[(x+khs)*istep_+ (y+khs)*jstep_] = vcl_exp(-xx*xx/(2*ssq))*yy*vcl_exp(-yy*yy/(2*ssq))/cc;
00114       }
00115     }
00116   }
00117 };
00118 
00119 //: simple Gaussian smoothing kernel
00120 //  K_x = G_x, K_y = G_y
00121 class brip_G_kernel : public brip_gaussian_kernel
00122 {
00123  public:
00124   brip_G_kernel(double sigma_, double dx_=0.0, double dy_=0.0): brip_gaussian_kernel(sigma_, dx_, dy_){}
00125   ~brip_G_kernel(){}
00126 
00127   //: compute the kernel
00128   virtual void compute_kernel(bool separated_kernels_only=false)
00129   {
00130     double ssq = sigma*sigma;
00131     double sq2pisig = vcl_sqrt(2*vnl_math::pi)*sigma;
00132 
00133     //1-d kernels
00134     for (int x = -khs; x <= khs; x++)
00135       K_x[x+khs] = vcl_exp(-(x-dx)*(x-dx)/(2*ssq))/sq2pisig;
00136     for (int y = -khs; y <= khs; y++)
00137       K_y[y+khs] = vcl_exp(-(y-dy)*(y-dy)/(2*ssq))/sq2pisig;
00138 
00139     if (!separated_kernels_only){
00140       for (unsigned i=0; i<ni_; i++){
00141         for (unsigned j=0; j<nj_; j++){
00142           top_left_[i*istep_+j*jstep_] = K_x[i]*K_y[j];
00143         }
00144       }
00145     }
00146   }
00147 };
00148 
00149 //: Gx kernel
00150 //  K_x = dG_x, K_y = G_y
00151 class brip_Gx_kernel : public brip_gaussian_kernel
00152 {
00153  public:
00154   brip_Gx_kernel(double sigma_, double dx_=0.0, double dy_=0.0): brip_gaussian_kernel(sigma_, dx_, dy_){}
00155   ~brip_Gx_kernel(){}
00156 
00157   //: compute the kernel
00158   virtual void compute_kernel(bool separated_kernels_only=false)
00159   {
00160     double ssq = sigma*sigma;
00161     double sq2pisig = vcl_sqrt(2*vnl_math::pi)*sigma;
00162 
00163     //1-d kernels
00164     for (int x = -khs; x <= khs; x++)
00165       K_x[x+khs] = -(x-dx)*vcl_exp(-(x-dx)*(x-dx)/(2*ssq))/(sq2pisig*ssq);
00166     for (int y = -khs; y <= khs; y++)
00167       K_y[y+khs] = vcl_exp(-(y-dy)*(y-dy)/(2*ssq))/sq2pisig;
00168 
00169     if (!separated_kernels_only){
00170       for (unsigned i=0; i<ni_; i++){
00171         for (unsigned j=0; j<nj_; j++){
00172           top_left_[i*istep_+j*jstep_] = K_x[i]*K_y[j];
00173         }
00174       }
00175     }
00176   }
00177 };
00178 
00179 //: Gy kernel
00180 //  K_x = G_x, K_y = dG_y
00181 class brip_Gy_kernel : public brip_gaussian_kernel
00182 {
00183  public:
00184   brip_Gy_kernel(double sigma_, double dx_=0.0, double dy_=0.0): brip_gaussian_kernel(sigma_, dx_, dy_){}
00185   ~brip_Gy_kernel(){}
00186 
00187   //: compute the kernel
00188   virtual void compute_kernel(bool separated_kernels_only=false)
00189   {
00190     double ssq = sigma*sigma;
00191     double sq2pisig = vcl_sqrt(2*vnl_math::pi)*sigma;
00192 
00193     //1-d kernels
00194     for (int x = -khs; x <= khs; x++)
00195       K_x[x+khs] = vcl_exp(-(x-dx)*(x-dx)/(2*ssq))/sq2pisig;
00196     for (int y = -khs; y <= khs; y++)
00197       K_y[y+khs] = -(y-dy)*vcl_exp(-(y-dy)*(y-dy)/(2*ssq))/(sq2pisig*ssq);
00198 
00199     if (!separated_kernels_only){
00200       for (unsigned i=0; i<ni_; i++){
00201         for (unsigned j=0; j<nj_; j++){
00202           top_left_[i*istep_+j*jstep_] = K_x[i]*K_y[j];
00203         }
00204       }
00205     }
00206   }
00207 };
00208 
00209 //: Gxx kernel
00210 //  K_x = d2G_x, K_y = G_y
00211 class brip_Gxx_kernel : public brip_gaussian_kernel
00212 {
00213  public:
00214   brip_Gxx_kernel(double sigma_, double dx_=0.0, double dy_=0.0): brip_gaussian_kernel(sigma_, dx_, dy_){}
00215   ~brip_Gxx_kernel(){}
00216 
00217   //: compute the kernel
00218   virtual void compute_kernel(bool separated_kernels_only=false)
00219   {
00220     double ssq = sigma*sigma;
00221     double sq2pisig = vcl_sqrt(2*vnl_math::pi)*sigma;
00222 
00223     //1-d kernels
00224     for (int x = -khs; x <= khs; x++)
00225       K_x[x+khs] = ((x-dx)*(x-dx)-ssq)*vcl_exp(-(x-dx)*(x-dx)/(2*ssq))/(sq2pisig*ssq*ssq);
00226     for (int y = -khs; y <= khs; y++)
00227       K_y[y+khs] = vcl_exp(-(y-dy)*(y-dy)/(2*ssq))/sq2pisig;
00228 
00229     if (!separated_kernels_only){
00230       for (unsigned i=0; i<ni_; i++){
00231         for (unsigned j=0; j<nj_; j++){
00232           top_left_[i*istep_+j*jstep_] = K_x[i]*K_y[j];
00233         }
00234       }
00235     }
00236   }
00237 };
00238 
00239 //: Gxy kernel
00240 //  K_x = dG_x, K_y = dG_y
00241 class brip_Gxy_kernel : public brip_gaussian_kernel
00242 {
00243  public:
00244   brip_Gxy_kernel(double sigma_, double dx_=0.0, double dy_=0.0): brip_gaussian_kernel(sigma_, dx_, dy_){}
00245   ~brip_Gxy_kernel(){}
00246 
00247   //: compute the kernel
00248   virtual void compute_kernel(bool separated_kernels_only=false)
00249   {
00250     double ssq = sigma*sigma;
00251     double sq2pisig = vcl_sqrt(2*vnl_math::pi)*sigma;
00252 
00253     //1-d kernels
00254     for (int x = -khs; x <= khs; x++)
00255       K_x[x+khs] = -(x-dx)*vcl_exp(-(x-dx)*(x-dx)/(2*ssq))/(sq2pisig*ssq);
00256     for (int y = -khs; y <= khs; y++)
00257       K_y[y+khs] = -(y-dy)*vcl_exp(-(y-dy)*(y-dy)/(2*ssq))/(sq2pisig*ssq);
00258 
00259     if (!separated_kernels_only){
00260       for (unsigned i=0; i<ni_; i++){
00261         for (unsigned j=0; j<nj_; j++){
00262           top_left_[i*istep_+j*jstep_] = K_x[i]*K_y[j];
00263         }
00264       }
00265     }
00266   }
00267 };
00268 
00269 //: Gyy kernel
00270 //  K_x = G_x, K_y = d2G_y
00271 class brip_Gyy_kernel : public brip_gaussian_kernel
00272 {
00273  public:
00274   brip_Gyy_kernel(double sigma_, double dx_=0.0, double dy_=0.0): brip_gaussian_kernel(sigma_, dx_, dy_){}
00275   ~brip_Gyy_kernel(){}
00276 
00277   //: compute the kernel
00278   virtual void compute_kernel(bool separated_kernels_only=false)
00279   {
00280     double ssq = sigma*sigma;
00281     double sq2pisig = vcl_sqrt(2*vnl_math::pi)*sigma;
00282 
00283     //1-d kernels
00284     for (int x = -khs; x <= khs; x++)
00285       K_x[x+khs] = vcl_exp(-(x-dx)*(x-dx)/(2*ssq))/sq2pisig;
00286     for (int y = -khs; y <= khs; y++)
00287       K_y[y+khs] = ((y-dy)*(y-dy)-ssq)*vcl_exp(-(y-dy)*(y-dy)/(2*ssq))/(sq2pisig*ssq*ssq);
00288 
00289     if (!separated_kernels_only){
00290       for (unsigned i=0; i<ni_; i++){
00291         for (unsigned j=0; j<nj_; j++){
00292           top_left_[i*istep_+j*jstep_] = K_x[i]*K_y[j];
00293         }
00294       }
00295     }
00296   }
00297 };
00298 
00299 //: Gxxx kernel
00300 //  K_x = d3G_x, K_y = G_y
00301 class brip_Gxxx_kernel : public brip_gaussian_kernel
00302 {
00303  public:
00304   brip_Gxxx_kernel(double sigma_, double dx_=0.0, double dy_=0.0): brip_gaussian_kernel(sigma_, dx_, dy_){}
00305   ~brip_Gxxx_kernel(){}
00306 
00307   //: compute the kernel
00308   virtual void compute_kernel(bool separated_kernels_only=false)
00309   {
00310     double ssq = sigma*sigma;
00311     double sq2pisig = vcl_sqrt(2*vnl_math::pi)*sigma;
00312 
00313     //1-d kernels
00314     for (int x = -khs; x <= khs; x++)
00315       K_x[x+khs] = (x-dx)*(3*ssq -(x-dx)*(x-dx))*vcl_exp(-(x-dx)*(x-dx)/(2*ssq))/(sq2pisig*ssq*ssq*ssq);
00316     for (int y = -khs; y <= khs; y++)
00317       K_y[y+khs] = vcl_exp(-(y-dy)*(y-dy)/(2*ssq))/sq2pisig;
00318 
00319     if (!separated_kernels_only){
00320       for (unsigned i=0; i<ni_; i++){
00321         for (unsigned j=0; j<nj_; j++){
00322           top_left_[i*istep_+j*jstep_] = K_x[i]*K_y[j];
00323         }
00324       }
00325     }
00326   }
00327 };
00328 
00329 //: Gxxy kernel
00330 //  K_x = d2G_x, K_y = dG_y
00331 class brip_Gxxy_kernel : public brip_gaussian_kernel
00332 {
00333  public:
00334   brip_Gxxy_kernel(double sigma_, double dx_=0.0, double dy_=0.0): brip_gaussian_kernel(sigma_, dx_, dy_){}
00335   ~brip_Gxxy_kernel(){}
00336 
00337   //: compute the kernel
00338   virtual void compute_kernel(bool separated_kernels_only=false)
00339   {
00340     double ssq = sigma*sigma;
00341     double sq2pisig = vcl_sqrt(2*vnl_math::pi)*sigma;
00342 
00343     //1-d kernels
00344     for (int x = -khs; x <= khs; x++)
00345       K_x[x+khs] = ((x-dx)*(x-dx)-ssq)*vcl_exp(-(x-dx)*(x-dx)/(2*ssq))/(sq2pisig*ssq*ssq);
00346     for (int y = -khs; y <= khs; y++)
00347       K_y[y+khs] = -(y-dy)*vcl_exp(-(y-dy)*(y-dy)/(2*ssq))/(sq2pisig*sigma*ssq);
00348 
00349     if (!separated_kernels_only){
00350       for (unsigned i=0; i<ni_; i++){
00351         for (unsigned j=0; j<nj_; j++){
00352           top_left_[i*istep_+j*jstep_] = K_x[i]*K_y[j];
00353         }
00354       }
00355     }
00356   }
00357 };
00358 
00359 //: Gxyy kernel
00360 //  K_x = dG_x, K_y = d2G_y
00361 class brip_Gxyy_kernel : public brip_gaussian_kernel
00362 {
00363  public:
00364   brip_Gxyy_kernel(double sigma_, double dx_=0.0, double dy_=0.0): brip_gaussian_kernel(sigma_, dx_, dy_){}
00365   ~brip_Gxyy_kernel(){}
00366 
00367   //: compute the kernel
00368   virtual void compute_kernel(bool separated_kernels_only=false)
00369   {
00370     double ssq = sigma*sigma;
00371     double sq2pisig = vcl_sqrt(2*vnl_math::pi)*sigma;
00372 
00373     //1-d kernels
00374     for (int x = -khs; x <= khs; x++)
00375       K_x[x+khs] = -(x-dx)*vcl_exp(-(x-dx)*(x-dx)/(2*ssq))/(sq2pisig*ssq);
00376     for (int y = -khs; y <= khs; y++)
00377       K_y[y+khs] = ((y-dy)*(y-dy)-ssq)*vcl_exp(-(y-dy)*(y-dy)/(2*ssq))/(sq2pisig*ssq*ssq);
00378 
00379     if (!separated_kernels_only){
00380       for (unsigned i=0; i<ni_; i++){
00381         for (unsigned j=0; j<nj_; j++){
00382           top_left_[i*istep_+j*jstep_] = K_x[i]*K_y[j];
00383         }
00384       }
00385     }
00386   }
00387 };
00388 
00389 //: Gyyy kernel
00390 //  K_x = G_x, K_y = d3G_y
00391 class brip_Gyyy_kernel : public brip_gaussian_kernel
00392 {
00393  public:
00394   brip_Gyyy_kernel(double sigma_, double dx_=0.0, double dy_=0.0): brip_gaussian_kernel(sigma_, dx_, dy_){}
00395   ~brip_Gyyy_kernel(){}
00396 
00397   //: compute the kernel
00398   virtual void compute_kernel(bool separated_kernels_only=false)
00399   {
00400     double ssq = sigma*sigma;
00401     double sq2pisig = vcl_sqrt(2*vnl_math::pi)*sigma;
00402 
00403     //1-d kernels
00404     for (int x = -khs; x <= khs; x++)
00405       K_x[x+khs] = vcl_exp(-(x-dx)*(x-dx)/(2*ssq))/sq2pisig;
00406     for (int y = -khs; y <= khs; y++)
00407       K_y[y+khs] = (y-dy)*(3*ssq -(y-dy)*(y-dy))*vcl_exp(-(y-dy)*(y-dy)/(2*ssq))/(sq2pisig*ssq*ssq*ssq);
00408 
00409     if (!separated_kernels_only){
00410       for (unsigned i=0; i<ni_; i++){
00411         for (unsigned j=0; j<nj_; j++){
00412           top_left_[i*istep_+j*jstep_] = K_x[i]*K_y[j];
00413         }
00414       }
00415     }
00416   }
00417 };
00418 
00419 #endif // brip_gaussian_kernel_h