#ifndef CANNY_H #define CANNY_H #include #include #include namespace icl { /// Class for the canny edge detector (IPP only!) /** This subsection describes a classic edge detector proposed by J.Canny. The detector uses a grayscale image as an input and outputs a black-and-white image, where non-zero pixels mark detected edges. The algorithm consists of three stages described below. Stage 1: Differentiation Assuming two-dimensional convolution, the image data are differentiated with respect to the directions x and y. The gradient of the surface of the convoluted image function in any direction is possible to compute from the known gradient in any two directions. From the computed x and y gradient values, the magnitude and angle of the slope can be calculated from the hypotenuse and arctangent. Note: Stage 1 is done by two sobel filters. The implementation can handle the output of the two sobel filters, or can handle a normal image, applying the sobel filters by itself. Stage 2: Non-Maximum Suppression With the rate of intensity change found at each point in the image, edges must now be placed at the points of maximum, or rather non-maximum must be suppressed. A local maximum occurs at a peak in the gradient function, or alternatively where the derivative of the gradient function is set to zero. However, in this case it is preferable to suppress non-maximum perpendicular to the edge direction, rather than parallel to the edge direction, since the edge strength is expected to continue along an extended contour. The algorithm starts off by reducing the angle of gradient to one of 4 sectors shown in Figure 14-1. The algorithm passes 3×3 neighborhood across the magnitude array. At each point, the center element of neighborhood is compared with its two neighbors along line of the gradient given by the sector value. If the central value is non-maximum, i.e., not greater than the neighbors, it is suppressed. Stage 3: Edge Thresholding streaking by setting an upper and lower edge value limit. Considering a line segment, if a value lies above the upper threshold limit it is immediately accepted. If the value lies below the low threshold it is immediately rejected. Points which lie between the two limits are accepted if they are connected to pixels which exhibit strong response. The likelihood of streaking is reduced drastically since the line segment points must fluctuate above the upper limit and below the lower limit for streaking to occur. J.Canny recommends the ratio of high to low limit be in the range two or three to one, based on predicted signal-to-noise ratios. */ class CannyOp : public UnaryOp { public: CannyOp(icl32f lowThresh=0, icl32f highThresh=255); CannyOp(UnaryOp *dxOp, UnaryOp *dyOp, icl32f lowThresh=0, icl32f highThresh=255, bool deleteOps=true); virtual ~CannyOp(); void setThresholds(icl32f lowThresh, icl32f highThresh); icl32f getLowThreshold() const; icl32f getHighThreshold() const; virtual void apply(const ImgBase *src, ImgBase **dst); private: /// buffer for ippiCanny icl8u* m_pucBuffer8u; int m_iBufferSize; ImgBase *m_apoDXY[2]; UnaryOp *m_apoDXYOps[2]; icl32f m_fLowThresh, m_fHighThresh; // internally used thresholds bool m_bDeleteOps; }; } // namespace icl #endif