filter_nonmaxsup.h

Go to the documentation of this file.
00001 //
00002 // more filters. this time non maxima suppression
00003 // (static)
00004 // stumeikle Sun May  5 20:48:34 2002
00005 //
00006 //
00007 
00008 #ifndef FILTER_NONMAXSUP_H
00009 #define FILTER_NONMAXSUP_H
00010 
00011 #include <boost/shared_array.hpp>
00012 #include "mimasexception.h"
00013 #include "filter.h"
00014 #include "image.h"
00015 #include "property_image.h"
00016 #include "edgel.h"
00017 #include <cmath>
00018 
00019 namespace mimas  {
00020   /*
00021     General image filter routines... continued. NonMax suppression filter is
00022     placed in this file. Chose to break up the original filter.h file to
00023     keep the file sizes down.
00024  $Header: /cvs/mimas2/include/filter_nonmaxsup.h,v 1.1.1.1 2005/08/09 15:37:45 engmb Exp $
00025    */
00029 template<typename T>
00030 void filter<T>::nonMaximaSuppression( const image<T>& gradx,
00031                                          const image<T>& grady,
00032                                          const image<T>& gradsq,
00033                                          double threshold,
00034                                          property_image& output )
00035   throw (mimasexception)
00036 {
00037     double   sqthres = (double)(threshold * threshold);
00038     output.init( gradsq.getWidth(), gradsq.getHeight());
00039 
00040     MMERROR( gradx.getWidth() == grady.getWidth() &&
00041              gradx.getWidth() == gradsq.getWidth() &&
00042              gradx.getHeight() == grady.getHeight() &&
00043              gradx.getHeight() == gradsq.getHeight(), mimasexception, ,
00044              "Trying to do non maxima suppression with images of different "
00045              "sizes" );
00046     
00047     int      w = gradx.getWidth();
00048     int      h = gradx.getHeight();
00049     boost::shared_array< double >
00050       rowx( new double[w] ),
00051       rowy( new double[w] ),
00052       grad( new double[w] ),
00053       grad_m1( new double[w] ),
00054       grad_p1( new double[w] );
00055 
00056     for(int y=1;y<(h-1);++y)
00057     {
00058   int x;
00059 
00060   //extract lots of rows and convert to double (@ WHY TINA?)
00061   for(x=0;x<w;++x)
00062   {
00063       rowx[x] = (double)gradx.pixel(x,y);
00064       rowy[x] = (double)grady.pixel(x,y);
00065       grad[x] = (double)gradsq.pixel(x,y);
00066       grad_p1[x]=(double)gradsq.pixel(x,y+1);
00067       grad_m1[x]=(double)gradsq.pixel(x,y-1);
00068   }
00069     
00070   for(x=1;x<(w-1);++x)
00071   {
00072       // now the messy guts ...
00073       double   a, b;
00074       double   st;
00075       double   del;
00076       double   dr, dc;
00077       double   gradratio, fabsgradratio;
00078 
00079       if (grad[x] < sqthres)
00080     continue;
00081 
00082       st = grad[x];
00083       gradratio = rowx[x] / rowy[x];
00084       fabsgradratio = (float)fabs(gradratio);
00085       if (fabsgradratio < 1.5 && fabsgradratio > 0.67)  // diagonal
00086       {
00087     if ((st < grad[x - 1] || st <= grad[x + 1]) &&
00088         (st < grad_m1[x]  || st <= grad_p1[x]))
00089         continue;
00090         
00091     if (gradratio > 0)  // right diagonal
00092     {
00093         if (st < grad_m1[x - 1] || st <= grad_p1[x + 1])
00094       continue;
00095         st = sqrt(st);
00096         a  = sqrt(grad_m1[x - 1]);
00097         b  = sqrt(grad_p1[x + 1]);
00098         del = (a - b) / ((a + b - st * 2) * 2);
00099         dr = (del + 0.5);
00100         dc = (del + 0.5);
00101     } else
00102     {
00103         if (st < grad_p1[x - 1] || st <= grad_m1[x + 1])
00104       continue;
00105         st = sqrt(st);
00106         a =  sqrt(grad_p1[x - 1]);
00107         b =  sqrt(grad_m1[x + 1]);
00108         del = (a - b) / ((a + b - st * 2) * 2);
00109         dr = (0.5 - del);
00110         dc = (del + 0.5);
00111     }
00112       } else if (fabs(rowx[x]) > fabs(rowy[x]))
00113       {
00114     if (st < grad[x - 1] || st <= grad[x + 1])
00115         continue;
00116     st = sqrt(st);
00117     a = sqrt(grad[x - 1]);
00118     b = sqrt(grad[x + 1]);
00119     del = (a - b) / ((a + b - st * 2) * 2);
00120     dr = 0.5;
00121     dc = (del + 0.5);
00122       } else
00123       {
00124     if (st < grad_m1[x] || st <= grad_p1[x])
00125         continue;
00126     st = sqrt(st);
00127     a = sqrt(grad_m1[x]);
00128     b = sqrt(grad_p1[x]);
00129     del = (a - b) / ((a + b - st * 2) * 2);
00130     dr = (del + 0.5);
00131     dc = 0.5; // pixel centre 
00132       }
00133 
00134       {
00135     int     ii, jj; // actual storage location 
00136 
00137     edgel_ptr ej( new edgel );
00138 
00139     //positions are measured relative to the image plane
00140     //(IMPORTANT)
00141     double  posx = (double)x + dc;
00142     ii = (int)floor(posx);
00143     double  posy = (double)y + dr;
00144     jj = (int)floor(posy);
00145     
00146     if (output.getPixel(ii,jj)) {
00147         // delete ej; //dont store >1 edgel per pixel
00148     } else
00149     {
00150         ej->setPosition( posx,posy );
00151         ej->setOrientation( angle( rowx[x], rowy[x]) );
00152         ej->setContrast( st );
00153         output.setPixel( ii,jj, ej );
00154     }
00155       }
00156   }
00157     }
00158 }
00159 
00161 
00162 }
00163 
00164 #endif

[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:17 2006, Bala Amavasai, Stuart Meikle, Arul Selvan, Fabio Caparrelli, Jan Wedekind, Manuel Boissenin, ...