00001 #ifndef osl_canny_rothwell_h 00002 #define osl_canny_rothwell_h 00003 //: 00004 // \file 00005 // 00006 // A class for performing traditional Canny edge detection. The basic 00007 // implementation is as close to that described in Canny's thesis 00008 // as possible, though sub-pixel interpolation of the final edge 00009 // output has been included, as has edge thinning. Note that there are 00010 // probably differences between this implementation and the documentation 00011 // (that is his Master's thesis). 00012 // 00013 // The improved implementation includes the patching of single pixel 00014 // gaps in the Edgel chains, as well as improved search for edgels near 00015 // to edgelchain terminations (dangling ends). At these places the scale 00016 // of the smoothing convolution kernel is reduced dynamically to remove 00017 // interference from corners (if they exist) near to the ends. Overall, 00018 // this yields a much better understanding of the image topology. 00019 // 00020 // Note that nothing special has been done around the border of the image; 00021 // we have simply ignored a border of size width_ all the way round. Perhaps 00022 // this should be changed to provide consistency with the rest of TargetJr. 00023 // 00024 // \author 00025 // Charlie Rothwell - 25/1/92 00026 // GE Corporate Research and Development 00027 // 00028 // \verbatim 00029 // Modifications 00030 // Samer Abdallah - 5/10/95 00031 // Robotics Research Group, Oxford University 00032 // Most members and methods placed in new base class osl_canny_rothwellBase. 00033 // Fixed bugs in Final_hysteresis() and Jump_single_pixels(). 00034 // \endverbatim 00035 00036 #include <osl/osl_canny_base.h> 00037 #include <vil1/vil1_image.h> 00038 00039 class osl_canny_rothwell_params; 00040 00041 class osl_canny_rothwell : public osl_canny_base 00042 { 00043 public: 00044 osl_canny_rothwell(osl_canny_rothwell_params const &); 00045 ~osl_canny_rothwell(); 00046 00047 void detect_edges(vil1_image const &image, vcl_list<osl_edge*>*, bool adaptive = false); 00048 00049 protected: 00050 void Non_maximal_suppression(); 00051 void Initial_hysteresis(); 00052 void Final_hysteresis(vcl_list<osl_edge*>*); 00053 void Jump_gap(int,int,int,int,int*,int*); 00054 void Thin_edges(); 00055 void Jump_single_breaks(); 00056 void Adaptive_Canny(vil1_image const &); 00057 void Compute_adaptive_images(int,int,int,float**,float**,float**); 00058 void Subtract_thick(int,int,int,float**); 00059 void Best_eight_way(int,int,float**,int*,int*); 00060 void Find_dangling_ends(); 00061 int Dangling_end(int,int); 00062 void Find_junctions(); 00063 void Find_junction_clusters(); 00064 00065 int **dangling_; // Binary image true only at dangling ends, and relevant lists 00066 vcl_list<int> *xdang_,*ydang_; 00067 float range_; // The maximal region of effect of the smallest smoothing kernel 00068 00069 // Parameters for the adaptive smoothing 00070 float old_sigma_; // Smoothing sigma 00071 int old_width_; // The smoothing kernel width 00072 int old_k_size_; // The kernel is 2*width_+1s 00073 00074 float dummy_; // A dummy intensity step value 00075 }; 00076 00077 #endif // osl_canny_rothwell_h