00001
00002
00003
00004
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
00022
00023
00024
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
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
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)
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)
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;
00132 }
00133
00134 {
00135 int ii, jj;
00136
00137 edgel_ptr ej( new edgel );
00138
00139
00140
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
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