00001
00002 #include "osl_canny_base.h"
00003
00004
00005
00006 #include <osl/osl_canny_port.h>
00007 #include <vcl_cmath.h>
00008 #include <vcl_list.h>
00009 #include <vcl_cassert.h>
00010
00011
00012
00013 osl_canny_base::osl_canny_base(float sigma, float low, float high, bool v)
00014 : xstart_(0), ystart_(0)
00015 , xsize_(0), ysize_(0)
00016
00017 , smooth_(0)
00018 , dx_(0)
00019 , dy_(0)
00020 , grad_(0)
00021
00022 , thick_(0)
00023 , thin_(0)
00024 , theta_(0)
00025
00026 , junction_(0)
00027 , jx_(0)
00028 , jy_(0)
00029 , xjunc_(0)
00030 , yjunc_(0)
00031 , vlist_(0)
00032
00033 , kernel_(0)
00034 {
00035 verbose =v;
00036 sigma_ = sigma;
00037 low_ = low;
00038 high_ = high;
00039 }
00040
00041
00042 osl_canny_base::~osl_canny_base() { }
00043
00044
00045
00046
00047
00048
00049
00050 void osl_canny_base::Initial_follow(float * const *thin, int xsize, int ysize, float low,
00051 int x, int y,
00052 vcl_list<int> *xc,
00053 vcl_list<int> *yc,
00054 vcl_list<float> *grad)
00055 {
00056
00057 if ( (x<=0) || (x>=xsize-1) || (y<=0) || (y>=ysize-1) )
00058 return;
00059
00060
00061
00062 xc->push_front(x);
00063 yc->push_front(y);
00064 grad->push_front(thin[x][y]);
00065 thin[x][y] = 0.0;
00066
00067
00068 if ( thin[x][y-1] > low )
00069 Initial_follow(thin, xsize, ysize, low, x ,y-1,xc,yc,grad);
00070 if ( thin[x-1][y ] > low )
00071 Initial_follow(thin, xsize, ysize, low, x-1,y ,xc,yc,grad);
00072 if ( thin[x ][y+1] > low )
00073 Initial_follow(thin, xsize, ysize, low, x ,y+1,xc,yc,grad);
00074 if ( thin[x+1][y ] > low )
00075 Initial_follow(thin, xsize, ysize, low, x+1,y ,xc,yc,grad);
00076 if ( thin[x+1][y-1] > low )
00077 Initial_follow(thin, xsize, ysize, low, x+1,y-1,xc,yc,grad);
00078 if ( thin[x-1][y-1] > low )
00079 Initial_follow(thin, xsize, ysize, low, x-1,y-1,xc,yc,grad);
00080 if ( thin[x-1][y+1] > low )
00081 Initial_follow(thin, xsize, ysize, low, x-1,y+1,xc,yc,grad);
00082 if ( thin[x+1][y+1] > low )
00083 Initial_follow(thin, xsize, ysize, low, x+1,y+1,xc,yc,grad);
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 void osl_canny_base::Final_follow(int x, int y,
00093 vcl_list<int> *xc,
00094 vcl_list<int> *yc,
00095 vcl_list<float> *grad,
00096 int reverse)
00097 {
00098
00099 assert ( x>0 && y>0);
00100 assert ( (unsigned int)x+1<xsize_);
00101 assert ( (unsigned int)y+1<ysize_);
00102
00103
00104
00105 if (!reverse) {
00106 xc->push_front(x);
00107 yc->push_front(y);
00108 grad->push_front(thin_[x][y]);
00109 }
00110 thin_[x][y] = 0.0;
00111
00112
00113 if ( (thin_[x ][y-1]>low_) && (junction_[x ][y-1]==0) )
00114 Final_follow(x,y-1,xc,yc,grad,0);
00115 else if ( (thin_[x-1][y ]>low_) && (junction_[x-1][y ]==0) )
00116 Final_follow(x-1,y,xc,yc,grad,0);
00117 else if ( (thin_[x ][y+1]>low_) && (junction_[x ][y+1]==0) )
00118 Final_follow(x,y+1,xc,yc,grad,0);
00119 else if ( (thin_[x+1][y ]>low_) && (junction_[x+1][y ]==0) )
00120 Final_follow(x+1,y,xc,yc,grad,0);
00121 else if ( (thin_[x+1][y-1]>low_) && (junction_[x+1][y-1]==0) )
00122 Final_follow(x+1,y-1,xc,yc,grad,0);
00123 else if ( (thin_[x-1][y-1]>low_) && (junction_[x-1][y-1]==0) )
00124 Final_follow(x-1,y-1,xc,yc,grad,0);
00125 else if ( (thin_[x-1][y+1]>low_) && (junction_[x-1][y+1]==0) )
00126 Final_follow(x-1,y+1,xc,yc,grad,0);
00127 else if ( (thin_[x+1][y+1]>low_) && (junction_[x+1][y+1]==0) )
00128 Final_follow(x+1,y+1,xc,yc,grad,0);
00129
00130
00131
00132
00133
00134 else if ( junction_[x ][y-1] && ((xc->size()>2)||(junction_[x ][y-1]!=chain_no_)) ) {
00135 xc->push_front(jx_[x ][y-1]); yc->push_front(jy_[x ][y-1]); grad->push_front(jval_);
00136 junction_[x ][y-1] = chain_no_;
00137 }
00138 else if ( junction_[x-1][y ] && ((xc->size()>2)||(junction_[x-1][y ]!=chain_no_)) ) {
00139 xc->push_front(jx_[x-1][y ]); yc->push_front(jy_[x-1][y ]); grad->push_front(jval_);
00140 junction_[x-1][y ] = chain_no_;
00141 }
00142 else if ( junction_[x ][y+1] && ((xc->size()>2)||(junction_[x ][y+1]!=chain_no_)) ) {
00143 xc->push_front(jx_[x ][y+1]); yc->push_front(jy_[x ][y+1]); grad->push_front(jval_);
00144 junction_[x ][y+1] = chain_no_;
00145 }
00146 else if ( junction_[x+1][y ] && ((xc->size()>2)||(junction_[x+1][y ]!=chain_no_)) ) {
00147 xc->push_front(jx_[x+1][y ]); yc->push_front(jy_[x+1][y ]); grad->push_front(jval_);
00148 junction_[x+1][y ] = chain_no_;
00149 }
00150 else if ( junction_[x+1][y-1] && ((xc->size()>2)||(junction_[x+1][y-1]!=chain_no_)) ) {
00151 xc->push_front(jx_[x+1][y-1]); yc->push_front(jy_[x+1][y-1]); grad->push_front(jval_);
00152 junction_[x+1][y-1] = chain_no_;
00153 }
00154 else if ( junction_[x-1][y-1] && ((xc->size()>2)||(junction_[x-1][y-1]!=chain_no_)) ) {
00155 xc->push_front(jx_[x-1][y-1]); yc->push_front(jy_[x-1][y-1]); grad->push_front(jval_);
00156 junction_[x-1][y-1] = chain_no_;
00157 }
00158 else if ( junction_[x-1][y+1] && ((xc->size()>2)||(junction_[x-1][y+1]!=chain_no_)) ) {
00159 xc->push_front(jx_[x-1][y+1]); yc->push_front(jy_[x-1][y+1]); grad->push_front(jval_);
00160 junction_[x-1][y+1] = chain_no_;
00161 }
00162 else if ( junction_[x+1][y+1] && ((xc->size()>2)||(junction_[x+1][y+1]!=chain_no_)) ) {
00163 xc->push_front(jx_[x+1][y+1]); yc->push_front(jy_[x+1][y+1]); grad->push_front(jval_);
00164 junction_[x+1][y+1] = chain_no_;
00165 }
00166 }
00167
00168
00169
00170
00171
00172 void osl_canny_base::Follow_junctions(int * const *junction,
00173 int x, int y,
00174 vcl_list<int> *xc,
00175 vcl_list<int> *yc)
00176 {
00177
00178
00179 xc->push_front(x);
00180 yc->push_front(y);
00181 junction[x][y] = 0;
00182
00183
00184 if ( junction[x ][y-1] )
00185 Follow_junctions(junction,x ,y-1,xc,yc);
00186 if ( junction[x-1][y ] )
00187 Follow_junctions(junction,x-1,y ,xc,yc);
00188 if ( junction[x ][y+1] )
00189 Follow_junctions(junction,x ,y+1,xc,yc);
00190 if ( junction[x+1][y ] )
00191 Follow_junctions(junction,x+1,y ,xc,yc);
00192 if ( junction[x+1][y-1] )
00193 Follow_junctions(junction,x+1,y-1,xc,yc);
00194 if ( junction[x-1][y-1] )
00195 Follow_junctions(junction,x-1,y-1,xc,yc);
00196 if ( junction[x-1][y+1] )
00197 Follow_junctions(junction,x-1,y+1,xc,yc);
00198 if ( junction[x+1][y+1] )
00199 Follow_junctions(junction,x+1,y+1,xc,yc);
00200 }
00201
00202
00203
00204
00205
00206 void osl_canny_base::Cluster_centre_of_gravity(int * const *jx, int * const *jy,
00207 vcl_list<int> &xc,
00208 vcl_list<int> &yc,
00209 int &x0, int &y0)
00210 {
00211 typedef vcl_list<int>::iterator it;
00212
00213 if ( xc.empty() )
00214 return;
00215
00216
00217 double x=0.0,y=0.0;
00218 for (it i=xc.begin(),j=yc.begin(); i!=xc.end() && j!=yc.end(); ++i, ++j) {
00219
00220 x += *i;
00221 y += *j;
00222 }
00223 x /= xc.size(); y /= yc.size();
00224
00225
00226 double dist = -1;
00227 for (it i=xc.begin(),j=yc.begin(); i!=xc.end() && j!=yc.end(); ++i, ++j) {
00228
00229
00230 double newdist;
00231 { double dx = x- *i, dy = y- *j; newdist = vcl_sqrt(dx*dx + dy*dy); }
00232 if ( dist<0 || newdist < dist ) {
00233 x0 = *i;
00234 y0 = *j;
00235 dist = newdist;
00236 }
00237 }
00238
00239
00240 for (it i=xc.begin(),j=yc.begin(); i!=xc.end() && j!=yc.end(); ++i,++j) {
00241
00242 jx[*i][*j] = x0;
00243 jy[*i][*j] = y0;
00244 }
00245 }
00246
00247
00248
00249
00250
00251
00252 int osl_canny_base::Junction_neighbour(int const * const *junction, int x, int y) {
00253
00254 if ( junction[x-1][y-1] || junction[x ][y-1] || junction[x+1][y-1] ||
00255 junction[x-1][y ] || junction[x+1][y ] ||
00256 junction[x-1][y+1] || junction[x ][y+1] || junction[x+1][y+1]
00257 )
00258 return 1;
00259 else
00260 return 0;
00261 }
00262
00263
00264
00265
00266
00267 template <class T>
00268 T **osl_canny_base_make_raw_image(int m, int n, T * ) {
00269 T *array = new T[m*n];
00270 T **data = new T* [m];
00271 for (int i =0; i < m; ++i)
00272 data[i] = &array[i*n];
00273 return data;
00274 }
00275
00276
00277 template <class T>
00278 void osl_canny_base_fill_raw_image(T * * image, int sizex, int sizey, T value) {
00279 for (int x =0; x < sizex; ++x)
00280 for (int y =0; y < sizey; ++y)
00281 image[x][y] = value;
00282 }
00283
00284
00285 template <class T>
00286 void osl_canny_base_free_raw_image(T **ptr) {
00287 T *array = ptr[0];
00288 fsm_delete_array array;
00289 fsm_delete_array ptr;
00290 }
00291
00292
00293 template <class S, class T>
00294 void osl_canny_base_copy_raw_image(S const * const *image1, T * const *image2, int m, int n)
00295 {
00296 for (int x=0; x<m; ++x)
00297 for (int y=0; y<n; ++y)
00298 image2[x][y] = image1[x][y];
00299 }
00300
00301
00302 #define inst(T) \
00303 template T **osl_canny_base_make_raw_image(int, int, T *dummy); \
00304 template void osl_canny_base_fill_raw_image(T **, int, int, T value); \
00305 template void osl_canny_base_free_raw_image(T **); \
00306 template void osl_canny_base_copy_raw_image(T const * const *, T * const *, int, int);
00307 inst(float);
00308 inst(int);
00309 #undef inst