00001 #ifndef gevd_step_h_ 00002 #define gevd_step_h_ 00003 //: 00004 // \file 00005 // \brief detection of step profiles in the intensity image 00006 // 00007 // Operator to implement Canny edge detector which finds elongated 00008 // step contours with dG. Then junctions are found by extending 00009 // from end points of dangling contours. 00010 // 00011 // The recipe is: 00012 // - Convolution with Gaussian with sigma typically = 1, 00013 // to well-condition the surface before taking first derivative. 00014 // Result is a smoothed image. 00015 // 00016 // - Convolution with first derivative, or first difference. 00017 // Result is a gradient image. Canny proves that first-derivative 00018 // of the Gaussian is the optimum filter to detect elongated 00019 // step profiles. 00020 // 00021 // - Optionally estimate sensor/texture sigma, if given noise 00022 // sigma is a negative interpolation factor -k in range -[0 1]. 00023 // noise_sigma = (1-k)*sensor_sigma + k*texture_sigma. 00024 // Sensor and texture sigmas are estimated from the histogram 00025 // of weak step edges, detected in an ROI centered on gradient image. 00026 // (see Step constructor documentation in Step.C - JLM) 00027 // 00028 // - Non Maximum suppression in the direction of local gradient, 00029 // to detect pixels with maximum local slope, above a priori 00030 // noise response. Result is connected contours, width < 2, 00031 // broken only at junctions with weaker chains. 00032 // Also obtain subpixel accuracy normal to the contour. 00033 // 00034 // - Optionally extend from end points of contours to search for 00035 // maximum slope in the direction normal to the dangling contours, 00036 // above some factor of the noise response. 00037 // Result is a simple detection of all strong junctions. 00038 // 00039 // Input: Intensity image, smoothing sigma, sensor/texture noise sigma 00040 // and threshold factors for detecting contour/junction edge elements. 00041 // 00042 // Output: Magnitude, direction, location of step pixels, forming 00043 // a connected network of contours. 00044 // 00045 // Complexity: O(|pixels|) time and space for convolutions. 00046 // O(|edgels|) time for iterative extension to recover junctions. 00047 // 00048 // \verbatim 00049 // Authors 00050 // John Canny (1986) SM Thesis 00051 // Chris Connolly (1987) use directional 1st-difference 00052 // Van-Duc Nguyen (1989) add subpixel location, extension to find junctions 00053 // Arron Heller (1992) translate from CLOS to C++ 00054 // Van-Duc Nguyen (1995) add noise estimation, use FloatOperators. 00055 // Joe Mundy (1997) expanded comments on some methods. Added gradient 00056 // magnitude, grad_mag, and gradient direction angle 00057 // buffer, angle, to cache between edgel detection phases. 00058 // \endverbatim 00059 //----------------------------------------------------------------------------- 00060 00061 #include <vcl_iosfwd.h> 00062 class gevd_bufferxy; 00063 00064 class gevd_step 00065 { 00066 public: 00067 gevd_step(float smooth_sigma=1, //!< spatial smoothing [0.5 2.0] 00068 float noise_sigma=-0.5, //!< sensor/texture intensity noise -[0 1] 00069 float contour_factor=1.0, //!< threshold factor for contour edgels 00070 float junction_factor=1.5); //!< threshold factor for junction edgels 00071 ~gevd_step(); 00072 00073 bool DetectEdgels(const gevd_bufferxy& image, //!< float image 00074 gevd_bufferxy*& edgels, //!< strength = dG * I 00075 gevd_bufferxy*& direction, //!< direction % PI/4 00076 gevd_bufferxy*& locationx, //!< subpixel loc 00077 gevd_bufferxy*& locationy, 00078 gevd_bufferxy*& grad_mag, //!< Gradient magnitude 00079 gevd_bufferxy*& angle); //!< Gradient orientation 00080 int RecoverJunctions(const gevd_bufferxy& image, //!< iterative extension 00081 gevd_bufferxy& edgels, //!< from end points of contours 00082 gevd_bufferxy& direction, 00083 gevd_bufferxy& locationx, gevd_bufferxy& locationy, 00084 int*& junctionx, int*& junctiony); 00085 00086 float NoiseSigma() const; //!< query stored/estimated noise sigma 00087 float NoiseResponse() const; //!< response of noise sigma to filter ddG 00088 float NoiseThreshold(bool shortp=false) const; //!< elongated/directional? 00089 00090 static float NoiseResponseToFilter(const float noiseSigma, 00091 const float smoothSigma, 00092 const float filterFactor); 00093 00094 friend vcl_ostream& operator<<(vcl_ostream& os, const gevd_step& st); 00095 friend vcl_ostream& operator<<(vcl_ostream& os, gevd_step& st); 00096 00097 protected: 00098 float smoothSigma; //!< spatial smoothing 00099 float noiseSigma; //!< sensor/texture noise 00100 float contourFactor, junctionFactor; //!< threshold factor for edgels 00101 float filterFactor; //!< factor in convolution filter 00102 }; 00103 00104 #endif // gevd_step_h_