Recent from talks
Nothing was collected or created yet.
Canny edge detector
View on Wikipedia| Feature detection |
|---|
| Edge detection |
| Corner detection |
| Blob detection |
| Ridge detection |
| Hough transform |
| Structure tensor |
| Affine invariant feature detection |
| Feature description |
| Scale space |
The Canny edge detector is an edge detection operator that uses a multi-stage algorithm to detect a wide range of edges in images. It was developed by John F. Canny in 1986. Canny also produced a computational theory of edge detection explaining why the technique works.
Development
[edit]Canny edge detection is a technique to extract useful structural information from different vision objects and dramatically reduce the amount of data to be processed. It has been widely applied in various computer vision systems. Canny has found that the requirements for the application of edge detection on diverse vision systems are relatively similar. Thus, an edge detection solution to address these requirements can be implemented in a wide range of situations. The general criteria for edge detection include:
- Detection of edge with low error rate, which means that the detection should accurately catch as many edges shown in the image as possible
- The edge point detected from the operator should accurately localize on the center of the edge.
- A given edge in the image should only be marked once, and where possible, image noise should not create false edges.
To satisfy these requirements Canny used the calculus of variations – a technique which finds the function which optimizes a given functional. The optimal function in Canny's detector is described by the sum of four exponential terms, but it can be approximated by the first derivative of a Gaussian.
Among the edge detection methods developed so far, Canny's algorithm is one of the most strictly defined methods that provides good and reliable detection. Owing to its optimality to meet with the three criteria for edge detection and the simplicity of the process for its implementation, it has become one of the most popular algorithms for edge detection.
Process
[edit]The process of Canny edge detection algorithm can be broken down to five different steps:
- Apply Gaussian filter to smooth the image in order to remove the noise
- Find the intensity gradients of the image
- Apply gradient magnitude thresholding or lower bound cut-off suppression to get rid of spurious response to edge detection
- Apply double threshold to determine potential edges
- Track edge by hysteresis: Finalize the detection of edges by suppressing all the other edges that are weak and not connected to strong edges.
Gaussian Filter
[edit]Since all edge detection results are easily affected by the noise in the image, it is essential to filter out the noise to prevent false detection caused by it. To smooth the image, a Gaussian filter kernel is convolved with the image. This step will slightly smooth the image to reduce the effects of obvious noise on the edge detector. The equation for a Gaussian filter kernel of size (2k+1)×(2k+1) is given by:
Here is an example of a 5×5 Gaussian filter, used to create the adjacent image, with = 2. (The asterisk denotes a convolution operation.)
It is important to understand that the selection of the size of the Gaussian kernel will affect the performance of the detector. The larger the size is, the lower the detector's sensitivity to noise. Additionally, the localization error to detect the edge will slightly increase with the increase of the Gaussian filter kernel size. A 5×5 is a good size for most cases, but this will also vary depending on specific situations.
Finding the intensity gradient of the image
[edit]An edge in an image may point in a variety of directions, so the Canny algorithm uses four filters to detect horizontal, vertical and diagonal edges in the blurred image. The edge detection operator (such as Roberts, Prewitt, or Sobel) returns a value for the first derivative in the horizontal direction (Gx) and the vertical direction (Gy). From this the edge gradient and direction can be determined:

- ,
where G can be computed using the hypot function and atan2 is the arctangent function with two arguments. The edge direction angle is rounded to one of four angles representing vertical, horizontal, and the two diagonals (0°, 45°, 90°, and 135°). An edge direction falling in each color region will be set to a specific angle value, for instance, θ in [0°, 22.5°] or [157.5°, 180°] maps to 0°.
Gradient magnitude thresholding or lower bound cut-off suppression
[edit]Minimum cut-off suppression of gradient magnitudes, or lower bound thresholding, is an edge thinning technique.
Lower bound cut-off suppression is applied to find the locations with the sharpest change of intensity value. The algorithm for each pixel in the gradient image is:
- Compare the edge strength of the current pixel with the edge strength of the pixel in the positive and negative gradient directions.
- If the edge strength of the current pixel is the largest compared to the other pixels in the mask with the same direction (e.g., a pixel that is pointing in the y-direction will be compared to the pixel above and below it in the vertical axis), the value will be preserved. Otherwise, the value will be suppressed.
In some implementations, the algorithm categorizes the continuous gradient directions into a small set of discrete directions, and then moves a 3x3 filter over the output of the previous step (that is, the edge strength and gradient directions). At every pixel, it suppresses the edge strength of the center pixel (by setting its value to 0) if its magnitude is not greater than the magnitude of the two neighbors in the gradient direction. For example,
- if the rounded gradient angle is 0° (i.e. the edge is in the north–south direction) the point will be considered to be on the edge if its gradient magnitude is greater than the magnitudes at pixels in the east and west directions,
- if the rounded gradient angle is 90° (i.e. the edge is in the east–west direction) the point will be considered to be on the edge if its gradient magnitude is greater than the magnitudes at pixels in the north and south directions,
- if the rounded gradient angle is 135° (i.e. the edge is in the northeast–southwest direction) the point will be considered to be on the edge if its gradient magnitude is greater than the magnitudes at pixels in the north-west and south-east directions,
- if the rounded gradient angle is 45° (i.e. the edge is in the northwest–southeast direction) the point will be considered to be on the edge if its gradient magnitude is greater than the magnitudes at pixels in the north-east and south-west directions.
In more accurate implementations, linear interpolation is used between the two neighbouring pixels that straddle the gradient direction. For example, if the gradient angle is between 89° and 180°, interpolation between gradients at the north and north-east pixels will give one interpolated value, and interpolation between the south and south-west pixels will give the other (using the conventions of the last paragraph). The gradient magnitude at the central pixel must be greater than both of these for it to be marked as an edge.
Note that the sign of the direction is irrelevant, i.e. north–south is the same as south–north and so on.
Double threshold
[edit]After application of non-maximum suppression, the remaining edge pixels provide a more accurate representation of real edges in an image. However, some edge pixels remain that are caused by noise and color variation. To account for these spurious responses, it is essential to filter out edge pixels with a weak gradient value and preserve edge pixels with a high gradient value. This is accomplished by selecting high and low threshold values. If an edge pixel’s gradient value is higher than the high threshold value, it is marked as a strong edge pixel. If an edge pixel’s gradient value is smaller than the high threshold value and larger than the low threshold value, it is marked as a weak edge pixel. If an edge pixel's gradient value is smaller than the low threshold value, it will be suppressed. The two threshold values are empirically determined and their definition will depend on the content of a given input image.
Edge tracking by hysteresis
[edit]
The strong edge pixels should certainly be involved in the final edge image; they are deemed to come from true edges in the image. However, there will be some debate on the weak edge pixels. We want to determine whether these pixels come from a true edge, or noise/color variations. Weak edge pixels should be dropped from consideration if it is the latter. This algorithm uses the idea that weak edge pixels from true edges will (usually) be connected to a strong edge pixel while noise responses are unconnected. To track the edge connection, blob analysis is applied by looking at a weak edge pixel and its 8-connected neighborhood pixels. As long as there is one strong edge pixel that is involved in the blob, that weak edge point can be identified as one that should be preserved. These weak edge pixels become strong edges that can then cause their neighboring weak edge pixels to be preserved.
Walkthrough of the algorithm
[edit]This section will show the progression of an image through each of the five steps.
Improvements
[edit]While traditional Canny edge detection provides a relatively simple but precise methodology for the edge detection problem, with more demanding requirements on the accuracy and robustness on the detection, the traditional algorithm can no longer handle the challenging edge detection task. The main defects of the traditional algorithm can be summarized as follows:[1]
- A Gaussian filter is applied to smooth out the noise, but it will also smooth the edge, which is considered as the high frequency feature. This will increase the possibility of missing weak edges, and the appearance of isolated edges in the result.
- For the gradient amplitude calculation, the old Canny edge detection algorithm uses the center in a small 2×2 neighborhood window to calculate the finite difference mean value to represent the gradient amplitude. This method is sensitive to noise and can easily detect false edges and lose real edges.
- In the traditional Canny edge detection algorithm, there will be two fixed global threshold values to filter out the false edges. However, as the image gets complex, different local areas will need very different threshold values to accurately find the real edges. In addition, the global threshold values are determined manually through experiments in the traditional method, which leads to a complexity of calculation when a large number of different images need to be dealt with.
- The result of the traditional detection cannot reach a satisfactory high accuracy of a single response for each edge - multi-point responses will appear.
In order to address these defects, an improvement to the canny edge algorithm is presented in the following paragraphs.
Replace Gaussian filter
[edit]As both edge and noise will be identified as a high frequency signal, a simple Gaussian filter will add a smooth effect on both of them. However, in order to reach high accuracy of detection of the real edge, it is expected that a more smooth effect should be applied to noise and a less smooth effect should be added to the edge. Bing Wang and Shaosheng Fan from Changsha University of Science and Technology developed an adaptive filter, where the filter will evaluate discontinuity between greyscale values of each pixel.[citation needed] The higher the discontinuity, the lower the weight value is set for the smooth filter at that point. Contrarily, the lower the discontinuity between the greyscale values, the higher the weight value is set to the filter. The process to implement this adaptive filter can be summarized in five steps:
- 1. K = 1, set the iteration n and the coefficient of the amplitude of the edge h.
- 2. Calculate the gradient value and
- 3. Calculate the weight according to the formulae below:
- 4. The definition of the adaptive filter is:
to smooth the image, where
- 5. When K = n, stop the iteration, otherwise, k = k+1, keep doing the second step
Improvement on gradient magnitude and direction calculation
[edit]The gradient magnitude and direction can be calculated with a variety of different edge detection operators, and the choice of operator can influence the quality of results. A very commonly chosen one is the 3x3 Sobel filter. However, other filters may be better, such as a 5x5 Sobel filter, which will reduce noise, or the Scharr filter, which has better rotational symmetry. Other common choices are Prewitt (used by Zhou[2]) and Roberts Cross.
Robust method to determine the dual-threshold value
[edit]In order to resolve the challenges where it is hard to determine the dual-threshold value empirically, Otsu's method[3] can be used on the non-maximum suppressed gradient magnitude image to generate the high threshold. The low threshold is typically set to 1/2 of the high threshold in this case. Since the gradient magnitude image is continuous-valued without a well-defined maximum, Otsu's method has to be adapted to use value/count pairs instead of a complete histogram.
The thinning of the edge
[edit]While the traditional Canny edge detection implements a good detection result to meet the first two criteria, it does not meet the single response per edge strictly. A mathematical morphology technique to thin the detected edge is developed by Mallat S and Zhong.[4]
Use of curvelets
[edit]Curvelets have been used in place of the Gaussian filter and gradient estimation to compute a vector field whose directions and magnitudes approximate the direction and strength of edges in the image, to which steps 3 - 5 of the Canny algorithm are then applied. Curvelets decompose signals into separate components of different scales, and dropping the components of finer scales can reduce noise.[5]
Differential geometric formulation
[edit]A more refined approach to obtain edges with sub-pixel accuracy is differential edge detection, where the requirement of non-maximum suppression is formulated in terms of second- and third-order derivatives computed from a scale space representation (Lindeberg 1998) – see the article on edge detection for a detailed description.
Variational formulation of the Haralick–Canny edge detector
[edit]A variational explanation for the main ingredient of the Canny edge detector, that is, finding the zero crossings of the 2nd derivative along the gradient direction, was shown to be the result of minimizing a Kronrod–Minkowski functional while maximizing the integral over the alignment of the edge with the gradient field (Kimmel and Bruckstein 2003). See the article on regularized Laplacian zero crossings and other optimal edge integrators for a detailed description.
Parameters
[edit]The Canny algorithm contains a number of adjustable parameters, which can affect the computation time and effectiveness of the algorithm.
- The size of the Gaussian filter: the smoothing filter used in the first stage directly affects the results of the Canny algorithm. Smaller filters cause less blurring, and allow detection of small, sharp lines. A larger filter causes more blurring, smearing out the value of a given pixel over a larger area of the image. Larger blurring radii are more useful for detecting larger, smoother edges – for instance, the edge of a rainbow.
- Thresholds: the use of two thresholds with hysteresis allows more flexibility than a single-threshold approach, but general problems of thresholding approaches still apply. A threshold set too high can miss important information. On the other hand, a threshold set too low will falsely identify irrelevant information (such as noise) as important. It is difficult to give a generic threshold that works well on all images. No tried and tested approach to this problem yet exists.
Conclusion
[edit]The Canny algorithm is adaptable to various environments. Its parameters allow it to be tailored to recognition of edges of differing characteristics depending on the particular requirements of a given implementation. In Canny's original paper, the derivation of the optimal filter led to a Finite Impulse Response filter, which can be slow to compute in the spatial domain if the amount of smoothing required is important (the filter will have a large spatial support in that case). For this reason, it is often suggested to use Rachid Deriche's infinite impulse response form of Canny's filter (the Canny–Deriche detector), which is recursive, and which can be computed in a short, fixed amount of time for any desired amount of smoothing. The second form is suitable for real time implementations in FPGAs or DSPs, or very fast embedded PCs. In this context, however, the regular recursive implementation of the Canny operator does not give a good approximation of rotational symmetry and therefore gives a bias towards horizontal and vertical edges.
See also
[edit]References
[edit]- ^ Li, Q., Wang, B., & Fan, S. (2009). Browse Conference Publications Computer Science and Engineer ... Help Working with Abstracts An Improved CANNY Edge Detection Algorithm. In 2009 Second International Workshop on Computer Science and Engineering proceedings : WCSE 2009 : 28–30 October 2009, Qingdao, China (pp. 497–500). Los Alamitos, CA: IEEE Computer Society
- ^ Zhou, P., Ye, W., & Wang, Q. (2011). An Improved Canny Algorithm for Edge Detection. Journal of Computational Information Systems, 7(5), 1516-1523.
- ^ Otsu N. A threshold selection method from gray-level histograms. IEEE Trans Systems, Man and Cybernetics,9(1):62-66,1979.
- ^ Mallat S, Zhong S. Characterization of Signals from Multi scale Edges [J]. IEEE Trans on PAMI, 1992, 14 (7):710-732.
- ^ Gebäck, T.; Koumoutsakos, P. (2009). "Edge detection in microscopy images using curvelets". BMC Bioinformatics. 10: 75. doi:10.1186/1471-2105-10-75. PMC 2663783. PMID 19257905.
- Canny, J., A Computational Approach To Edge Detection, IEEE Transactions on Pattern Analysis and Machine Intelligence, 8(6):679–698, 1986.
- R. Deriche, Using Canny's criteria to derive a recursively implemented optimal edge detector, Int. J. Computer Vision, Vol. 1, pp. 167–187, April 1987.
- Lindeberg, Tony "Edge detection and ridge detection with automatic scale selection", International Journal of Computer Vision, 30, 2, pp 117—154, 1998. (Includes the differential approach to non-maximum suppression.)
- Kimmel, Ron and Bruckstein, Alfred M. "On regularized Laplacian zero crossings and other optimal edge integrators", International Journal of Computer Vision, 53(3):225–243, 2003. (Includes the geometric variational interpretation for the Haralick–Canny edge detector.)
- Moeslund, T. (2009, March 23). Canny Edge Detection. Retrieved December 3, 2014
- Thomas B. Moeslund. Image and Video Processing. August 2008
- Green, B. (2002, January 1). Canny Edge Detection Tutorial. Retrieved December 3, 2014; archived here
External links
[edit]Canny edge detector
View on GrokipediaIntroduction
Overview
The Canny edge detector is a multi-stage algorithm designed for detecting edges in images while effectively suppressing noise, aiming to achieve optimal performance in computer vision tasks.[1] Edge detection in computer vision involves identifying boundaries or contours where the intensity of the image changes abruptly, providing essential information about object shapes and structures.[1] Developed by John F. Canny in 1986, the algorithm optimizes edge detection based on three key criteria: low error rate to minimize false detections and missed edges, well-localized edges to ensure precise positioning, and a single response per edge to avoid multiple detections of the same boundary.[1] At a high level, the Canny edge detector operates through four primary stages: noise reduction via smoothing to enhance reliability in noisy environments, computation of intensity gradients to highlight potential edge locations, non-maximum suppression to thin edges and retain only the strongest responses, and thresholding with hysteresis to connect and validate edge segments.[1] This structured approach allows the detector to produce clean, continuous edge maps suitable for further analysis in applications like object recognition. Compared to simpler first-order derivative methods such as the Sobel operator, the Canny edge detector offers superior robustness to noise through its initial smoothing step, more accurate edge localization via gradient direction analysis and suppression, and reduced false positives by enforcing a single response criterion. Originally motivated by the needs of multi-scale edge detection in robotic vision systems, it has become a foundational technique for extracting reliable boundaries in grayscale images.[1]Historical Development
The Canny edge detector originated from the work of John F. Canny during his time at the Massachusetts Institute of Technology (MIT). In 1983, as part of his Master's thesis titled "Finding Edges and Lines in Images," Canny proposed a novel framework for edge detection that emphasized optimality through explicitly defined criteria.[7] This thesis laid the groundwork for the algorithm, which was later formalized and published in 1986 in the IEEE Transactions on Pattern Analysis and Machine Intelligence under the title "A Computational Approach to Edge Detection." The publication marked a significant advancement in low-level image processing, building directly on the thesis by providing a comprehensive computational implementation suitable for practical use in vision systems. The development was motivated by the shortcomings of earlier edge detection techniques prevalent in the 1970s and early 1980s. Methods like the Sobel operator, introduced in the late 1960s, relied on simple finite-difference approximations to compute intensity gradients but were highly susceptible to noise, often producing fragmented or false edges in real images. Similarly, the Marr-Hildreth operator, proposed in 1980, used zero-crossings of the Laplacian of a Gaussian to identify edges, offering improved localization accuracy but struggling with noise rejection and requiring computationally intensive second-order derivatives. Canny aimed to overcome these limitations by designing an optimal detector that balanced three key performance measures: low error rates in detecting true edges (good detection), precise positioning of detected edges relative to actual boundaries (good localization), and a minimal number of responses per edge to avoid redundancy (single response criterion). Canny's approach drew from influential prior surveys and theoretical foundations in the field. Notably, Azriel Rosenfeld's comprehensive review of edge and curve detection techniques in 1971, along with his later contributions to image analysis in the early 1980s, highlighted the need for more robust operators in scene analysis. Following its publication, the Canny edge detector saw early adoption in computer vision applications at research institutions, including MIT's Artificial Intelligence Laboratory, where it supported tasks in object recognition, stereo matching, and robotic perception during the mid-to-late 1980s.Core Algorithm
Gaussian Smoothing
The Gaussian smoothing step in the Canny edge detector reduces noise in the input image to prevent false edges from arising in gradient computations, thereby enhancing the overall accuracy of edge detection. This process is essential for optimizing the signal-to-noise ratio while maintaining edge integrity, as raw images often contain high-frequency noise that mimics edge signals.[8] The smoothing employs a two-dimensional Gaussian kernel defined by the function where represents the standard deviation, determining the extent of the smoothing effect. This isotropic kernel weights pixels closer to the center more heavily, effectively blurring the image in a rotationally symmetric manner.[8] To obtain the smoothed image , the original image intensity is convolved with the Gaussian kernel , yielding . The convolution integrates the kernel over the image neighborhood at each pixel, producing a low-pass filtered version that attenuates noise without introducing ringing artifacts common in other filters.[8] The parameter is typically chosen between 1 and 2 pixels to achieve effective noise reduction for most natural images. Smaller values of preserve sharper edges but may retain more noise, whereas larger values increase blur, risking the displacement or broadening of true edges.[9][8] This smoothing introduces a fundamental trade-off: it suppresses noise to facilitate reliable gradient estimation but must avoid over-blurring, which could compromise the localization of edges in later stages of the algorithm. The choice of thus directly influences the detector's performance in balancing detection accuracy and edge precision.[8]Intensity Gradient Computation
Following the Gaussian smoothing stage, the intensity gradient is computed from the resulting smoothed image to identify regions of rapid intensity change that may correspond to edges. This step approximates the first-order partial derivatives of the image intensity function using finite differences, which provide a discrete measure of local intensity variations; the rationale for this approximation lies in its ability to efficiently capture edge strength as the rate of change while being robust to minor noise perturbations when applied post-smoothing.[1] In the original formulation, the gradient is computed using the first derivative of the Gaussian function. In practice, the Sobel operators are widely adopted for this computation due to their simplicity and effectiveness in estimating gradients with reduced sensitivity to noise compared to simpler differencing methods. The horizontal gradient component is obtained by convolving with the 3×3 kernel: The vertical gradient component uses the transposed kernel: These kernels perform a weighted central difference, emphasizing central pixels for derivative approximation while smoothing adjacent ones to mitigate noise. The gradient magnitude at each pixel, representing edge strength, is then calculated as ; for efficiency in implementations, this is often approximated by the Manhattan distance , which avoids the computationally intensive square root while preserving relative edge strengths. The gradient direction , indicating the orientation of the maximum intensity change, is computed as , yielding angles in the range . To simplify subsequent processing, is quantized into four principal directions: 0° (east-west), 45° (northeast-southwest), 90° (north-south), and 135° (northwest-southeast). The outputs are two dense maps: the magnitude map , which intensifies pixels near potential edges, and the direction map , which orients these candidates for further refinement in the algorithm.[1]Non-Maximum Suppression
Non-maximum suppression is a critical step in the Canny edge detection algorithm that refines the gradient magnitude map by retaining only pixels corresponding to local maxima along the direction of the intensity gradient, thereby thinning edges to a single pixel width and improving localization accuracy.[8] This process eliminates the broad, multi-pixel ridges produced by the preceding gradient computation, ensuring that only the strongest ridge points—those most likely to represent true edges—are preserved, while suppressing weaker adjacent points that could lead to false or blurred edge detections.[10] The procedure operates on the computed gradient magnitude and direction at each pixel, where indicates the local edge normal.[8] For a given pixel, the magnitude is compared to the magnitudes of its immediate neighbors lying along the gradient direction (or its opposite). Typically, is quantized into four directions (0°, 45°, 90°, 135°), and comparisons are made accordingly—for instance, at 0°, the pixel's magnitude is checked against its left and right neighbors. If is not strictly greater than both neighboring magnitudes, the pixel is suppressed by setting its value to zero in the output map.[10] The resulting output is a thinned edge map consisting solely of ridge pixels that form continuous, one-pixel-wide edge contours, minimizing streakiness and preparing the image for further edge validation.[10]Double Thresholding
Double thresholding is a key step in the Canny edge detection algorithm, applied following non-maximum suppression to classify potential edge pixels based on their gradient magnitudes into strong edges, weak edges, or non-edges. This process uses two empirically determined thresholds: a high threshold and a low threshold , where is typically set to 2 to 3 times to balance edge detection sensitivity and noise rejection.[8] Pixels in the thinned gradient magnitude map are classified as follows: a strong edge if the magnitude , a weak edge if , or suppressed (non-edge) if .[8] The rationale for employing dual thresholds lies in their ability to identify robust, high-contrast edges via the high threshold while provisionally retaining lower-contrast segments that may form part of continuous edges, thereby mitigating the fragmentation caused by noise without incorporating spurious isolated responses.[8] Threshold values are set empirically depending on the image characteristics and desired edge sensitivity; for grayscale images with pixel intensities ranging from 0 to 255, common examples include and , achieving the recommended ratio while adapting to typical gradient scales.[11] This step produces an initial edge map where strong edges are definitively marked, weak edges are provisionally indicated, and non-edges are excluded, setting the stage for further refinement.[8]Edge Tracking by Hysteresis
Edge tracking by hysteresis is the final stage in the Canny edge detection algorithm, which refines the edge map produced by double thresholding to form continuous contours while suppressing noise-induced artifacts. After classifying gradient magnitudes into strong edges (above the high threshold), weak edges (between high and low thresholds), and non-edges (below the low threshold), the hysteresis process begins by marking all strong edge pixels as definite edges in the output. It then examines the 8-connected neighborhood of these strong pixels, promoting connected weak edge pixels to strong status if they form part of the same contour, thereby bridging minor discontinuities.[8] The connectivity in this mechanism relies on an 8-neighbor search, where edge tracing starts from each strong pixel and follows paths through adjacent weak pixels, stopping only when encountering non-edge pixels or the end of a potential contour. This spatial continuity requirement ensures that only weak edges physically linked to strong ones are retained, effectively connecting segments that might otherwise appear as isolated or broken lines due to minor gradient fluctuations. As described in the original formulation, "if any part of a contour is above a high threshold, those points are immediately output, as is the entire connected segment of contour which contains the points and which lies above a low threshold."[8] The primary purpose of hysteresis is to leverage the contextual relationship between edge strengths along a contour, reducing false positives from isolated weak edges caused by noise while preserving meaningful, closed edge structures that exhibit spatial coherence. By requiring weak edges to be adjacent to strong ones, it minimizes streaking—short, spurious edge segments—and enhances the detection of true object boundaries that may have small gaps from threshold variations. This approach achieves a balance between sensitivity to genuine edges and robustness to interruptions, typically using a high-to-low threshold ratio of 2:1 or 3:1 to optimize continuity without over-accepting noise.[8] The output of edge tracking by hysteresis is a clean binary edge map, where retained edges (both original strong and promoted weak pixels) are set to a high value (e.g., 255), and all suppressed pixels (isolated weak edges and non-edges) are set to zero, resulting in thin, unbroken lines representing the detected contours. This final map effectively handles gaps up to the scale of the low threshold by propagating the strong edge label along connected paths, ensuring that small discontinuities in the gradient do not fragment important edges.[8]Algorithm Walkthrough
Step-by-Step Example
To illustrate the Canny edge detector in practice, consider a simple grayscale test image of a coin against a uniform background, with added Gaussian noise to simulate real-world conditions. This synthetic image features a sharp circular edge at an intensity transition, contaminated by speckles that could produce false edges. The process begins with Gaussian smoothing using σ = 1.4, which convolves the input with a 2D Gaussian kernel to reduce noise while preserving edge sharpness; the resulting smoothed image shows diminished speckles, with the coin's boundary slightly blurred but the overall contrast maintained.[5] Next, intensity gradient computation yields a magnitude map where pixel values highlight potential edges; in this example, the coin's circumference shows high gradient strength, while residual noise creates weak scattered responses, localizing the primary edge to a narrow band around the circle. Non-maximum suppression then thins the gradient map by retaining only local maxima perpendicular to the gradient direction, producing a suppressed map with a single-pixel-wide edge along the coin's rim; this step eliminates streaks from broad gradient plateaus caused by the smoothing, minimizing artifacts like fuzzy boundaries.[5] Double thresholding follows with low threshold T_low = 50 and high threshold T_high = 100, classifying strong edges (>100) as definite, weak edges (50-100) as potential, and others as non-edges; the thresholded map displays the coin's full contour as strong edges, with minor internal noise segments as weak or discarded, highlighting how this binary step filters out noise-induced candidates. Finally, edge tracking by hysteresis connects weak edges to adjacent strong ones, filling small gaps from noise interruptions to form a continuous closed loop around the coin; the output is a clean binary edge image with the isolated circular boundary, demonstrating gap filling that suppresses isolated weak segments.[5] Such transformations are commonly visualized in software like MATLAB'sedge function with the 'canny' method or OpenCV's cv2.Canny implementation, where intermediate maps can be plotted sequentially to observe noise reduction and edge localization.[12][5]
Pseudocode Implementation
The Canny edge detector algorithm processes a grayscale input image to produce a binary edge map as output, emphasizing thin, continuous edges while minimizing false detections. The implementation assumes access to basic image processing functions, such as convolution, and handles edge cases like image boundaries through padding and zero gradients by skipping normalization where magnitude is zero. The following high-level pseudocode outlines the core steps, drawing from the original formulation which prioritizes noise reduction, accurate localization, and response criteria.[1] Gradient magnitude is typically computed using the Euclidean norm √(G_x² + G_y²); a common approximation for efficiency in implementations is |G_x| + |G_y|, using integer arithmetic to reduce computational overhead without significant loss in accuracy.function CannyEdgeDetector(image, sigma, low_threshold, high_threshold):
# Step 1: Gaussian Smoothing
gaussian_kernel = generateGaussianKernel(sigma) # 2D Gaussian, e.g., size 5x5 or separable
smoothed = convolve(image, gaussian_kernel) # Pad boundaries with zeros or replication
# Step 2: Intensity Gradient Computation
# Compute partial derivatives using Sobel operators or derivative of Gaussian
G_x = convolve(smoothed, sobel_x_kernel) # Horizontal [gradient](/page/Gradient), e.g., [[-1,0,1],[-2,0,2],[-1,0,1]]
G_y = convolve(smoothed, sobel_y_kernel) # Vertical [gradient](/page/Gradient), e.g., [[-1,-2,-1],[0,0,0],[1,2,1]]
# [Gradient](/page/Gradient) magnitude (precise)
magnitude = sqrt(G_x^2 + G_y^2)
# [Gradient](/page/Gradient) direction (in degrees, handle zero magnitude case)
direction = []
for each pixel (i,j):
if magnitude[i][j] == [0](/page/0):
direction[i][j] = [0](/page/0) # Arbitrary, no edge
else:
angle = atan2(G_y[i][j], G_x[i][j]) * 180 / PI
# Quantize to [0](/page/0), 45, 90, 135 degrees
if angle < [0](/page/0):
angle += 180
if (0 <= angle < 22.5) or (157.5 <= angle <= 180):
direction[i][j] = [0](/page/0) # East
elif 22.5 <= angle < 67.5:
direction[i][j] = 45 # Northeast
elif 67.5 <= angle < 112.5:
direction[i][j] = 90 # North
else:
direction[i][j] = 135 # Northwest
# Step 3: Non-Maximum Suppression
suppressed = zeros_like(magnitude)
for each pixel (i,j) where magnitude[i][j] > [0](/page/0): # Skip zeros
# Get neighboring pixels based on quantized direction (handle boundaries)
neighbors = getInterpolatedNeighbors(magnitude, i, j, direction[i][j]) # Two relevant directions
if magnitude[i][j] >= neighbors[0] and magnitude[i][j] >= neighbors[1]:
suppressed[i][j] = magnitude[i][j]
# Else suppress to [0](/page/0) (thin edge)
# Step 4: Double Thresholding
edges = zeros_like(suppressed, dtype=boolean)
weak = zeros_like(suppressed, dtype=boolean)
for each pixel (i,j):
if suppressed[i][j] > high_threshold:
edges[i][j] = true # Strong edge
elif suppressed[i][j] > low_threshold:
weak[i][j] = true # Potential weak edge
# Step 5: Edge Tracking by [Hysteresis](/page/Hysteresis)
# Use connected component tracing (e.g., DFS or BFS) to link weak to strong edges
for each pixel (i,j) where edges[i][j] == true: # Start from strong edges
traceEdges(i, j, weak, edges) # [Flood fill](/page/Flood_fill): mark connected weak pixels as edges
return edges # Binary edge map (true = edge)
function traceEdges(i, j, weak, edges):
# BFS queue for [hysteresis](/page/Hysteresis) tracing
queue = enqueue((i,j))
edges[i][j] = true # Already strong, propagate
while queue not empty:
(x, y) = dequeue()
# Check 8-neighbors (handle boundaries)
for each neighbor (nx, ny) in 8-connectivity:
if valid(nx, ny) and weak[nx][ny] and not edges[nx][ny]:
edges[nx][ny] = true
enqueue((nx, ny))
# Stop if strong edge found, but continue for weak chains
function CannyEdgeDetector(image, sigma, low_threshold, high_threshold):
# Step 1: Gaussian Smoothing
gaussian_kernel = generateGaussianKernel(sigma) # 2D Gaussian, e.g., size 5x5 or separable
smoothed = convolve(image, gaussian_kernel) # Pad boundaries with zeros or replication
# Step 2: Intensity Gradient Computation
# Compute partial derivatives using Sobel operators or derivative of Gaussian
G_x = convolve(smoothed, sobel_x_kernel) # Horizontal [gradient](/page/Gradient), e.g., [[-1,0,1],[-2,0,2],[-1,0,1]]
G_y = convolve(smoothed, sobel_y_kernel) # Vertical [gradient](/page/Gradient), e.g., [[-1,-2,-1],[0,0,0],[1,2,1]]
# [Gradient](/page/Gradient) magnitude (precise)
magnitude = sqrt(G_x^2 + G_y^2)
# [Gradient](/page/Gradient) direction (in degrees, handle zero magnitude case)
direction = []
for each pixel (i,j):
if magnitude[i][j] == [0](/page/0):
direction[i][j] = [0](/page/0) # Arbitrary, no edge
else:
angle = atan2(G_y[i][j], G_x[i][j]) * 180 / PI
# Quantize to [0](/page/0), 45, 90, 135 degrees
if angle < [0](/page/0):
angle += 180
if (0 <= angle < 22.5) or (157.5 <= angle <= 180):
direction[i][j] = [0](/page/0) # East
elif 22.5 <= angle < 67.5:
direction[i][j] = 45 # Northeast
elif 67.5 <= angle < 112.5:
direction[i][j] = 90 # North
else:
direction[i][j] = 135 # Northwest
# Step 3: Non-Maximum Suppression
suppressed = zeros_like(magnitude)
for each pixel (i,j) where magnitude[i][j] > [0](/page/0): # Skip zeros
# Get neighboring pixels based on quantized direction (handle boundaries)
neighbors = getInterpolatedNeighbors(magnitude, i, j, direction[i][j]) # Two relevant directions
if magnitude[i][j] >= neighbors[0] and magnitude[i][j] >= neighbors[1]:
suppressed[i][j] = magnitude[i][j]
# Else suppress to [0](/page/0) (thin edge)
# Step 4: Double Thresholding
edges = zeros_like(suppressed, dtype=boolean)
weak = zeros_like(suppressed, dtype=boolean)
for each pixel (i,j):
if suppressed[i][j] > high_threshold:
edges[i][j] = true # Strong edge
elif suppressed[i][j] > low_threshold:
weak[i][j] = true # Potential weak edge
# Step 5: Edge Tracking by [Hysteresis](/page/Hysteresis)
# Use connected component tracing (e.g., DFS or BFS) to link weak to strong edges
for each pixel (i,j) where edges[i][j] == true: # Start from strong edges
traceEdges(i, j, weak, edges) # [Flood fill](/page/Flood_fill): mark connected weak pixels as edges
return edges # Binary edge map (true = edge)
function traceEdges(i, j, weak, edges):
# BFS queue for [hysteresis](/page/Hysteresis) tracing
queue = enqueue((i,j))
edges[i][j] = true # Already strong, propagate
while queue not empty:
(x, y) = dequeue()
# Check 8-neighbors (handle boundaries)
for each neighbor (nx, ny) in 8-connectivity:
if valid(nx, ny) and weak[nx][ny] and not edges[nx][ny]:
edges[nx][ny] = true
enqueue((nx, ny))
# Stop if strong edge found, but continue for weak chains