1 #ifndef gevd_step_h_ 2 #define gevd_step_h_ 3 //: 4 // \file 5 // \brief detection of step profiles in the intensity image 6 // 7 // Operator to implement Canny edge detector which finds elongated 8 // step contours with dG. Then junctions are found by extending 9 // from end points of dangling contours. 10 // 11 // The recipe is: 12 // - Convolution with Gaussian with sigma typically = 1, 13 // to well-condition the surface before taking first derivative. 14 // Result is a smoothed image. 15 // 16 // - Convolution with first derivative, or first difference. 17 // Result is a gradient image. Canny proves that first-derivative 18 // of the Gaussian is the optimum filter to detect elongated 19 // step profiles. 20 // 21 // - Optionally estimate sensor/texture sigma, if given noise 22 // sigma is a negative interpolation factor -k in range -[0 1]. 23 // noise_sigma = (1-k)*sensor_sigma + k*texture_sigma. 24 // Sensor and texture sigmas are estimated from the histogram 25 // of weak step edges, detected in an ROI centered on gradient image. 26 // (see Step constructor documentation in Step.C - JLM) 27 // 28 // - Non Maximum suppression in the direction of local gradient, 29 // to detect pixels with maximum local slope, above a priori 30 // noise response. Result is connected contours, width < 2, 31 // broken only at junctions with weaker chains. 32 // Also obtain subpixel accuracy normal to the contour. 33 // 34 // - Optionally extend from end points of contours to search for 35 // maximum slope in the direction normal to the dangling contours, 36 // above some factor of the noise response. 37 // Result is a simple detection of all strong junctions. 38 // 39 // Input: Intensity image, smoothing sigma, sensor/texture noise sigma 40 // and threshold factors for detecting contour/junction edge elements. 41 // 42 // Output: Magnitude, direction, location of step pixels, forming 43 // a connected network of contours. 44 // 45 // Complexity: O(|pixels|) time and space for convolutions. 46 // O(|edgels|) time for iterative extension to recover junctions. 47 // 48 // \verbatim 49 // Authors 50 // John Canny (1986) SM Thesis 51 // Chris Connolly (1987) use directional 1st-difference 52 // Van-Duc Nguyen (1989) add subpixel location, extension to find junctions 53 // Arron Heller (1992) translate from CLOS to C++ 54 // Van-Duc Nguyen (1995) add noise estimation, use FloatOperators. 55 // Joe Mundy (1997) expanded comments on some methods. Added gradient 56 // magnitude, grad_mag, and gradient direction angle 57 // buffer, angle, to cache between edgel detection phases. 58 // \endverbatim 59 //----------------------------------------------------------------------------- 60 61 #include <iostream> 62 #include <iosfwd> 63 #ifdef _MSC_VER 64 # include <vcl_msvc_warnings.h> 65 #endif 66 class gevd_bufferxy; 67 68 class gevd_step 69 { 70 public: 71 gevd_step(float smooth_sigma=1, //!< spatial smoothing [0.5 2.0] 72 float noise_sigma=-0.5, //!< sensor/texture intensity noise -[0 1] 73 float contour_factor=1.0, //!< threshold factor for contour edgels 74 float junction_factor=1.5); //!< threshold factor for junction edgels 75 ~gevd_step(); 76 77 bool DetectEdgels(const gevd_bufferxy& image, //!< float image 78 gevd_bufferxy*& edgels, //!< strength = dG * I 79 gevd_bufferxy*& direction, //!< direction % PI/4 80 gevd_bufferxy*& locationx, //!< subpixel loc 81 gevd_bufferxy*& locationy, 82 gevd_bufferxy*& grad_mag, //!< Gradient magnitude 83 gevd_bufferxy*& angle); //!< Gradient orientation 84 int RecoverJunctions(const gevd_bufferxy& image, //!< iterative extension 85 gevd_bufferxy& edgels, //!< from end points of contours 86 gevd_bufferxy& direction, 87 gevd_bufferxy& locationx, gevd_bufferxy& locationy, 88 int*& junctionx, int*& junctiony) const; 89 90 float NoiseSigma() const; //!< query stored/estimated noise sigma 91 float NoiseResponse() const; //!< response of noise sigma to filter ddG 92 float NoiseThreshold(bool shortp=false) const; //!< elongated/directional? 93 94 static float NoiseResponseToFilter(const float noiseSigma, 95 const float smoothSigma, 96 const float filterFactor); 97 98 friend std::ostream& operator<<(std::ostream& os, const gevd_step& st); 99 friend std::ostream& operator<<(std::ostream& os, gevd_step& st); 100 101 protected: 102 float smoothSigma; //!< spatial smoothing 103 float noiseSigma; //!< sensor/texture noise 104 float contourFactor, junctionFactor; //!< threshold factor for edgels 105 float filterFactor{2}; //!< factor in convolution filter 106 }; 107 108 #endif // gevd_step_h_ 109