corner_tool.h

Go to the documentation of this file.
00001 //
00002 // harris and stevens corner detection
00003 // stumeikle Tue May  7 21:16:45 2002
00004 //
00005 
00006 #ifndef HSCORNER_FILTER_H
00007 #define HSCORNER_FILTER_H
00008 
00009 #include "filter.h"
00010 #include "image.h"
00011 #include "image_op.h"
00012 #include "gauss.h"
00013 #include "filter_grad.h"
00014 #include "property_image.h"
00015 #include "corner.h"
00016 
00017 namespace mimas {
00018   
00031 template<typename T>
00032 class corner_tool
00033 {
00034     private:
00035   //actually most of these aren't used!
00036   double   sigma, maxError;   
00037   double   thres;       
00038   double   lowd, upd, width;    
00039   double   disp ;       
00040   double   uniqueness, correlate, asymetry ;
00041   double   tuniqueness, tcorrelate, tasymetry;
00042   double   theight, twidth ;    
00043   double   patch_sigma;     
00044   int      stereo_images;     
00045   int      fixed_matches;     
00046   int      good_matches;      
00047 
00048     public:
00049   corner_tool()
00050   {
00051       sigma = 1.0, maxError = 0.5 / 256.0, thres = 6.0;
00052       lowd = -0.5, upd = 0.5, width = 3.0;
00053       disp = 0;
00054       uniqueness = 0.004, correlate = 0.985, asymetry= 0.85;
00055       tuniqueness = 0.001, tcorrelate = 0.980, tasymetry = 0.85;
00056       theight = 20.0, twidth = 60.0;
00057       patch_sigma = 3.0;
00058       stereo_images = 1;
00059       fixed_matches = 0;
00060       good_matches = 0;
00061   }
00062 
00063   corner_tool(double t)
00064   {
00065       sigma = 1.0, maxError = 0.5 / 256.0, thres = t;
00066       lowd = -0.5, upd = 0.5, width = 3.0;
00067       disp = 0;
00068       uniqueness = 0.004, correlate = 0.985, asymetry= 0.85;
00069       tuniqueness = 0.001, tcorrelate = 0.980, tasymetry = 0.85;
00070       theight = 20.0, twidth = 60.0;
00071       patch_sigma = 3.0;
00072       stereo_images = 1;
00073       fixed_matches = 0;
00074       good_matches = 0;
00075   }
00076 
00077   void  setThreshold( double t ) 
00078   {
00079       thres = t;
00080   }
00081 
00082   void filterImage( image<T> &input, corner_image &corner_im )
00083   {
00084       image<T>    gradx,grady,outsq;
00085       image<T>    gim;
00086       image<T>    peak_im;
00087       //corner_image  corner_im;
00088 
00089       doCornerExtract( input, sigma, maxError, 0.05, peak_im, gradx, grady );
00090       gim = gaussBlur< float >( peak_im, sigma, maxError );
00091       peak_im.clear();
00092       findMaxima( gim, 1024.0*thres,0,corner_im);
00093       cornerLocate( gim, gradx, grady, corner_im );
00094   }
00095 
00096 
00097 private:
00098   void  doCornerExtract( image<T>& im, double sigma, double maxError,
00099          double edge_sup, image<T>& output_im, image<T>& gradx,
00100          image<T>& grady )
00101   {
00102      if ( &output_im != &im && &output_im != &gradx && &output_im != &grady )
00103        output_im.init( im.getWidth(), im.getHeight() );
00104 
00105       filter<T>::gradX( im, gradx );
00106       filter<T>::gradY( im, grady );
00107 
00108       image<T>
00109          gradsqx ( gradx * gradx ),
00110          gradsqy ( grady * grady ),
00111          gradsqxy( gradx * grady ),
00112          gradsqxsqy( gradsqx + gradsqy );
00113 
00114       image<T>  gimx, gimy, gimxy, gimedge;
00115 
00116       gimx = gaussBlur< float >( gradsqx, sigma, maxError );
00117       gradsqx.clear();
00118       gimy = gaussBlur< float >( gradsqy, sigma, maxError );
00119       gradsqy.clear();
00120       gimxy = gaussBlur< float >( gradsqxy, sigma, maxError );
00121       gradsqxy.clear();
00122 
00123       gimedge = gaussBlur< float >( gradsqxsqy, 1.1 * sigma, maxError );
00124       gradsqxsqy.clear();
00125 
00126       //now do corner im 2!!!!!! argggg
00127       doCornerExtract2(gimx,gimy,gimxy,gimedge,edge_sup, output_im);
00128 
00130   }
00131 
00132 
00133   void  doCornerExtract2( const image<T>& im1, const image<T>& im2,
00134                            const image<T>& im3, const image<T>& im4,
00135                            double edge_supp, image<T>&  output ) const
00136   {
00137      MMERROR( im1.getSize() == im2.getSize(),
00138               mimasexception, , "corner_tool::doCornerExtract2 - "
00139               "Images 1 and 2 are of different size." );
00140      MMERROR( im1.getSize() == im3.getSize(),
00141               mimasexception, , "corner_tool::doCornerExtract2 - "
00142               "Images 1 and 3 are of different size." );
00143      MMERROR( im1.getSize() == im4.getSize(),
00144               mimasexception, , "corner_tool::doCornerExtract2 - "
00145               "Images 1 and 4 are of different size." );
00146      MMERROR( im1.getSize() == output.getSize(),
00147               mimasexception, , "corner_tool::doCornerExtract2 - "
00148               "Image 1 and output image are of different size." );
00149      const T
00150        *p1 = im1.rawData(),
00151        *p2 = im2.rawData(),
00152        *p3 = im3.rawData(),
00153        *p4 = im4.rawData();
00154      T *q = output.rawData();
00155 
00156      for ( int i=0; i<(signed)output.getSize(); i++ ) {
00157        *q = (T)( (double)*p1 * (double)*p2 -
00158                  (double)*p3 * (double)*p3 -
00159                  edge_supp * (double)*p4 * (double)*p4 );
00160        p1++; p2++; p3++; p4++; q++;
00161      };
00162   }
00163 
00164   void  findMaxima(const image<T> &input, double thres, int num,
00165       corner_image& output) 
00166   {
00167        output.init( input.getWidth(), input.getHeight() );
00168 
00169       int wm1 = input.getWidth()-1;
00170       int hm1 = input.getHeight()-1;
00171       int nmax;
00172       double pix;
00173 
00174       for(int y=1;y<hm1;++y)
00175       {
00176          const T
00177            *max = input.rawData() + y * input.getWidth(),
00178            *max_m1 = max - input.getWidth(),
00179            *max_p1 = max + input.getWidth();
00180     for(int x=1;x<wm1;++x)
00181     {
00182 
00183         pix = (double) max[x];
00184         if (pix<thres)
00185           continue;
00186 
00187         nmax = 0;
00188 
00189         if (pix<max_m1[x-1] && ++nmax > num) continue;
00190         if (pix<max_m1[x]   && ++nmax > num) continue;
00191         if (pix<max_m1[x+1] && ++nmax > num) continue;
00192         if (pix<max[x-1]    && ++nmax > num) continue;
00193         if (pix<max[x+1]    && ++nmax > num) continue;
00194         if (pix<max_p1[x-1] && ++nmax > num) continue;
00195         if (pix<max_p1[x]   && ++nmax > num) continue;
00196         if (pix<max_p1[x+1] && ++nmax > num) continue;
00197 
00198         corner_ptr c( new corner );
00199 
00200         c->setPosition((double)x+0.5,(double)y+0.5);
00201         c->setOrientation(angle(0));
00202         c->setContrast( sqrt(pix) );
00203 
00204         if (!output.pixel(x,y))
00205           output.pixel( x,y ) = c;
00206     }
00207       }
00208   }
00209 
00210 
00211   void  cornerLocate( image<T>& corner_im,
00212             image<T>& gradx, image<T>& grady,
00213             corner_image& im ) 
00214   {
00215       int x,y;
00216       double  rx,ry;
00217 
00218       for(y=0;y<im.getHeight();++y)
00219       {
00220     for(x=0;x<im.getWidth();x++)
00221     {
00222         // we ASSUME here that the propery image contains only corners
00223           corner_ptr c( boost::dynamic_pointer_cast< corner >
00224                            ( im.pixel(x,y) ) );
00225 
00226         if (!c) continue;
00227 
00228         //process the corner and provide estimates of its orientation and
00229         //actual sub pixel position
00230         c->setContrast( sqrt(quadFit( corner_im, x,y, &rx, &ry )) );
00231         c->setPosition( rx,ry );
00232         c->setOrientation( cornerOrient(rx,ry, 10.0, gradx, grady ) );
00233     }
00234       }
00235   }
00236 
00237     double  quadFit( image<T>& image, int xin, int yin, double * px, double *py )
00238     {
00239   double  x,y;
00240   x = (double)xin;
00241   y = (double)yin;
00242 
00243   int n,m;
00244   double  pixval[3][3];
00245   for(n=0;n<3;++n)
00246   {
00247       for(m=0;m<3;++m)
00248       {
00249           pixval[n][m] = image.getPixel( xin+m-1, yin+n-1 );
00250       }
00251   }
00252 
00253   double           a, b, c, d, e, f;
00254   double          inter;
00255         double           temp;
00256   double    xs,ys;
00257 
00258         a = pixval[1][1];
00259         b = (pixval[0][2] - pixval[0][0]
00260     + pixval[1][2] - pixval[1][0]
00261     + pixval[2][2] - pixval[2][0]) / 6.0;
00262         c = (pixval[2][0] - pixval[0][0]
00263     + pixval[2][1] - pixval[0][1]
00264     + pixval[2][2] - pixval[0][2]) / 6.0;
00265         d = (pixval[0][0] - 2.0 * pixval[0][1] + pixval[0][2]
00266     + 3.0 * pixval[1][0] - 6.0 * pixval[1][1] + 3.0 * pixval[1][2]
00267     + pixval[2][0] - 2.0 * pixval[2][1] + pixval[2][2]) / 10.0;
00268         e = (pixval[0][0] - pixval[2][0]
00269     + pixval[2][2] - pixval[0][2]) / 4.0;
00270         f = (pixval[0][0] + 3.0 * pixval[0][1] + pixval[0][2]
00271     - 2.0 * pixval[1][0] - 6.0 * pixval[1][1] - 2.0 * pixval[1][2]
00272     + pixval[2][0] + 3.0 * pixval[2][1] + pixval[2][2]) / 10.0;
00273 
00274         temp = 4.0 * d * f - e * e;
00275         *px = 1.5 + x + (e * c - 2 * f * b) / temp;
00276         *py = 1.5 + y + (e * b - 2 * d * c) / temp;
00277 
00278         xs = (e * c - 2 * f * b) / temp;
00279         ys = (e * b - 2 * d * c) / temp;
00280 
00281         inter = a + b * xs + c * ys + d * xs * xs + e * xs * ys + f * ys * ys;
00282 
00283         return (inter); 
00284     }
00285 
00286 
00287     angle 
00288     cornerOrient(double rx,double ry, double range,
00289      image<T>& gradx, image<T>& grady )
00290     {
00291 
00292         int lx,ux,ly,uy,x,y;
00293         double meanx=0.0,meany=0.0;
00294         double dx,dy, delx,dely;
00295         double twosigma2 = range*range/2.0; // set the scale of radial weighting
00296   double weight;
00297         double thresh=0.0;
00298         double pix,v;
00299   angle orient;
00300 
00301         lx = (int)(rx-range-1.0);
00302   ux = (int)(rx+range+2);
00303         ly = (int)(ry-range-1.0);
00304         uy = (int)(ry+range+2);
00305 
00306         image<double> grad;
00307         grad.init( ux-lx, uy-ly );
00308 
00309   // calculate a robust mean with which to threshold the likely edge pixels 
00310   for (y=ly;y<uy;++y)
00311   {
00312           for (x=lx;x<ux;++x)
00313           {
00314           dx = (double)gradx.getPixel( x,y );
00315           dy = (double)grady.getPixel( x,y );
00316     v  = dx*dx+dy*dy;
00317     grad.setPixel( x-lx, y-ly, v );
00318           thresh += v;
00319           }
00320   }
00321 
00322   thresh /= (double)((ux-lx)*(uy-ly));
00323 
00324   // calculate the orientation from the moments of the thresholded gradient image
00325   for (y=ly+1;y<uy-1;++y)
00326   {
00327           for (x=lx+1;x<ux-1;++x)
00328           {
00329           if ((pix=grad.getPixel(x-lx,y-ly)) > thresh)
00330           {
00331                   delx = (double)x + 0.5 - rx;
00332                   dely = (double)y + 0.5 - ry;
00333 
00334                   if (delx*delx + dely*dely < twosigma2*2.0) weight = 1.0;
00335                   else weight = 0.0;
00336                   meanx += delx*weight;
00337                   meany += dely*weight;
00338           }
00339           }
00340   }
00341 
00342         if (meanx ==0) orient = angle(0); /* ### should be undefined */
00343   else
00344           orient = angle(meany,meanx);
00345 
00346         return(orient);
00347     }
00348 
00349 };
00350 
00351 };
00352 
00353 #endif
00354 

[GNU/Linux] [Qt] [Mesa] [STL] [Lapack] [Boost] [Magick++] [Xalan-C and Xerces-C] [doxygen] [graphviz] [FFTW] [popt] [xine] [Gnuplot] [gnu-arch] [gcc] [gstreamer] [autoconf/automake/make] [freshmeat.net] [opensource.org] [sourceforge.net] [MMVL]
mimas 2.1 - Copyright Mon Oct 30 11:31:16 2006, Bala Amavasai, Stuart Meikle, Arul Selvan, Fabio Caparrelli, Jan Wedekind, Manuel Boissenin, ...