00001 //-*- c++ -*------------------------------------------------------------------- 00002 #ifndef osl_edge_detector_h 00003 #define osl_edge_detector_h 00004 // 00005 // .NAME osl_edge_detector - Charlie's topological edge detector: 00006 // .INCLUDE osl/osl_edge_detector.h 00007 // .FILE osl_edge_detector.cxx 00008 // 00009 // .SECTION Description 00010 // A class for performing topologically-accurate edgel detection. NB: this 00011 // implementation is (unintentionally) stochastic, so you don't necessarily 00012 // get the same results from the same image. 00013 // 00014 // The basic implementation is based on that described in Canny's thesis 00015 // in that we compute the norm of the gradient, but then we use 00016 // non-maximal suppression dynamically to set the edge strength 00017 // thresholds. Non-maximal suppression is actually done using a 00018 // varient of Tsai-Fu thinning, and not as described in Canny's 00019 // thesis. 00020 // 00021 // Full documentation is given in INRIA technical report 2444, 1994. 00022 // 00023 // .SECTION Author: 00024 // Charlie Rothwell - 5/10/94 00025 // INRIA, Sophia Antipolis 00026 // 00027 // .SECTION Modifications: 00028 // CAR March 1995: improved memory management so that computation 00029 // time is reduced. Re-use of certain large arrays. Tried to 00030 // re-write Set_thresholds() to use Delauney triangulation rather 00031 // than Chamfer filtering. This didn't work as computation time 00032 // became far too high. 00033 // 00034 // JLM May 1995: Added a mask in Compute_gradient to support 00035 // edge detection within a polygonal region. Should add a similar 00036 // test in smoothing and derivative iterations for maximum 00037 // efficiency, but it isn't clear that there would be a big overall 00038 // gain, given the computation of IsMasked(x,y). 00039 // 00040 // JLM May 1995: Added a histogram of edgel strengths as an 00041 // additional output to support edgel change detection. The 00042 // histogram is constructed in Set_thresholds 00043 // 00044 // JLM May 1995 Added a new Do_edge_detector signature 00045 // to output an edgel group which bundles edgel chains and 00046 // gradient statistics together. 00047 // 00048 // JLM May 1997 Modified the formation of the gradient histogram 00049 // computation so that values are accumulated only 00050 // along edgel chains. New accumulation is in 00051 // Follow_curves(edges). The old code is still in place 00052 // but commented out. (Look for "May") The old code 00053 // just histogrammed the gradient magintude. 00054 // JLM June 1997 Found a bug in the above change which failed if 00055 // ghist_ is NULL. 00056 // JLM Dec 1997 Moved sigma_, low_, gauss_tail_ and verbose_ 00057 // up to osl_edge_detector_params and added new syle 00058 // constructors and execution 00059 //----------------------------------------------------------------------------- 00060 00061 #include <osl/osl_canny_port.h> 00062 #include <osl/osl_edge_detector_params.h> 00063 #include <vil1/vil1_image.h> 00064 00065 struct osl_edge_detector : public osl_edge_detector_params 00066 { 00067 osl_edge_detector(osl_edge_detector_params const &); 00068 00069 ~osl_edge_detector(); 00070 00071 void detect_edges(vil1_image const &image, 00072 vcl_list<osl_edge*> *edges, 00073 bool maintain_topology = true); 00074 00075 private: 00076 void Sub_pixel_interpolation(); 00077 void Thicken_threshold(int,int); 00078 void Set_thresholds(); 00079 void Fill_holes(); 00080 void Thin_edges(); 00081 void Follow_curves(vcl_list<osl_edge*>*); 00082 void Follow(int,int,vcl_list<int>*,vcl_list<int>*,vcl_list<float>*,int); 00083 00084 void Find_junctions(); 00085 void Find_junction_clusters(); 00086 void Follow_junctions(int,int,vcl_list<int>*,vcl_list<int>*); 00087 void Cluster_centre(vcl_list<int>&,vcl_list<int>&,int&,int&); 00088 00089 private: 00090 unsigned int width_; // The smoothing kernel width 00091 unsigned int k_size_; // The kernel is 2*width_+1s 00092 float *kernel_; // 1-Dimensional convolution kernel of size k_size 00093 00094 unsigned int xstart_,ystart_; // The origin of the buffer in the image 00095 unsigned int xsize_,ysize_; // The width of the image buffer 00096 00097 float **dx_; // Derivatives in x, and sub-pixel x coordinates 00098 float **dy_; // Derivatives in y, and sub-pixel y coordinates 00099 float **grad_; // Gradient image, and various other storage images 00100 float **smooth_; // Smoothed image. 00101 00102 // Quite a few of the following could be done using hash tables 00103 float **thin_; // Gradient image after thinning 00104 float **theta_; // Orientation image 00105 float **thresh_; // Image of the different thresholds used (replacing low) 00106 00107 int **dist_; // Distance transform image 00108 int **junction_; // Image true only at junctions ends, and relevant lists 00109 int **jx_,**jy_; // Images of (x,y) coordinates of nearest cluster centre 00110 vcl_list<int> *xjunc_,*yjunc_; 00111 vcl_list<osl_Vertex*> *vlist_; // The junction cluster centres 00112 00113 float jval_; // A dummy junction intensity step value 00114 int chain_no_; // A dummy variable used in following 00115 00116 int vertidcount_; // A counter used for setting vertex identifiers 00117 00118 // Added a histogram of edge gradient magnitudes - JLM May 1995 00119 bool gradient_histogram_; // Do we need to compute one? 00120 float max_gradient_; // Added May 1997 - JLM 00121 int histogram_resolution_; // The number of buckets in the histogram 00122 //Histogram* ghist_; 00123 }; 00124 00125 #endif // osl_edge_detector_h
1.7.5.1