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