What is Canny edge detection?

Canny edge detection is a popular and widely used edge detection technique that aims to identify and extract the edges of objects within an image. It was developed by John F. Canny in 1986 and has since become a fundamental tool in computer vision and image analysis.

Edge detection is a technique used in image processing to find the boundaries of the objects within the image. An edge is defined as a sudden change in pixel intensity within an image. Edges represent the boundaries between distinct objects or regions with varying intensity levels.

Canny edge detection algorithm

The Canny edge detection algorithm is a multistage process that helps to identify the edges in an image by reducing noise and preserving important edge features.

Image to detect edges
1 of 7

Let’s find out how it actually works:

Step 1: Grayscale conversion

The first step in the Canny edge detection algorithm is to convert the input image into grayscale. Grayscale images have a single channel representing the intensity of each pixel, which simplifies the edge detection process and reduces computational complexity. Grayscale conversion removes the color information from the image while preserving the relative brightness levels.

Color images are typically represented in three channels which are red, green, and blue (RGB). Each channel contains the intensity of the corresponding color component at each pixel. In contrast, grayscale images contain only one channel, where the pixel values represent the brightness or luminance levels.

The conversion to grayscale is achieved by taking a weighted sum of the RGB channels to calculate the grayscale intensity value for each pixel. The weights used in this transformation may vary depending on the application or convention.

Using a cv2 library, we can directly read an image in grayscale by specifying the cv2.IMREAD_GRAYSCALE:

import cv2
# Load an image in gray scale
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

Step 2: Noise reduction

The first step in the Canny edge detection algorithm is to apply a Gaussian filter to the input image. The Gaussian filter is a smoothing operation that helps to reduce noise in the image. Noise can introduce false edges, which could compromise the accuracy of the edge detection process. The Gaussian filter smooths the image by convolving it with a Gaussian kernel, effectively reducing high-frequency noise while preserving the edges’ sharpness.

Mathematically, the Gaussian kernel is defined as:

where:

  • x and y are the spatial coordinates of the kernel.

  • π is the mathematical constant Pi (approximately 3.14159).

  • σ is the standard deviation, controlling the width of the Gaussian distribution.

The Gaussian filter is applied to each pixel in the image by sliding the kernel across the entire image and taking the weighted average of the neighboring pixels’ intensities. This means it takes into account the brightness of surrounding pixels and gives more importance to the closer ones. So, if the kernel is larger, it involves more pixels in the calculation, resulting in a stronger blurring effect on the image.

Step 3: Gradient calculation

After reducing noise, the Canny algorithm proceeds to compute the gradient of the smoothed image. The gradient measures how fast the intensity changes at each pixel’s location. The algorithm uses the concept of derivatives, typically the Sobel operator, to determine both the gradient magnitude and orientation for each pixel. The gradient magnitude indicates the strength of the intensity change, while the gradient orientation specifies the direction of the steepest change.

The Sobel operator is a technique used to find the gradient, or the rate of change, in both the horizontal (from left to right) and vertical (from top to bottom) directions of an image. It’s commonly used for edge detection in image processing. The formulas for the Sobel operators are as follows:

Horizontal Sobel Operator (GxGx)

Vertical Sobel Operator (GyGy)

To calculate the gradient of an image using the Sobel operator, we slide these small 3 by 3 matrices (GxGx and GyGy) over the image, pixel by pixel. At each pixel, we perform a convolution operation, which involves multiplying the values of the surrounding pixels by the corresponding values in the Sobel operator matrices and then summing up the results.

By applying the Sobel operator in both horizontal and vertical directions, we obtain two separate gradient images. Combining these two gradient images can help us identify edges and boundaries in the original image. The magnitude and direction of the gradients provide valuable information about the intensity and direction of the edges in the image. To calculate the gradient magnitude GG and orientation θθ at each pixel, the following equations are used:

Formula for magnitude (GG)

Formula for orientation (θ\theta)

Step 4: Non-maximum suppression

Now that we have computed the gradient magnitude and orientation at each pixel, we move on to the critical step of Non-Maximum Suppression. This step effectively thins out the edges and produces a cleaner representation of the actual edges in the image.

Non-maximum suppression in the Canny edge detection algorithm works by examining each pixel's gradient magnitude and orientation and comparing it with the neighboring pixels along the gradient direction. If the central pixel's gradient magnitude is the largest among its neighbors, it means that this pixel is likely part of an edge, and we keep it. If not, we suppress it by setting its intensity to zero and removing it from consideration as an edge pixel.

Step 5: Double thresholding

The next step involves double thresholding to categorize edges into three categories: strong edges, weak edges, and non-edges.

A high threshold and a low threshold are used for this purpose.

  • Pixels with gradient magnitudes above the high threshold are considered strong edges, indicating significant intensity changes.

  • Pixels with gradient magnitudes between low threshold and high threshold are classified as weak edges. These weak edges may represent real edges or noise, and they need further verification.

  • Pixels with gradient magnitudes below the low threshold are considered non-edges and are discarded.

Step 6: Edge tracking by hysteresis

The last step of the Canny edge detection algorithm is edge tracking by hysteresis. Hysteresis means 'remembering the past' to make our edges more accurate and reliable. This step aims to link weak edges that are likely part of real edges to the strong edges. Starting from each strong edge pixel, the algorithm traces the edge by considering its neighboring weak edge pixels that are connected. If a weak edge pixel is connected to a strong edge pixel, it is also considered part of the edge and retained. This process continues until no more weak edges are connected. This ensures that the edges are continuous and well-defined.

Advantages of Canny edge detection

The Canny edge detection algorithm offers several advantages over other edge detection techniques:

  1. Accurate edge localization: Canny edge detection provides precise localization of edges. The non-maximum suppression step ensures that only the most significant edges are retained.

  2. Low error rate: By using double thresholding and edge tracking by hysteresis, the Canny algorithm reduces the likelihood of false edges and thus has a low error rate.

  3. Single response to edges: Each edge in the image is only represented by a single response in the output, avoiding duplicate edge detections.

  4. Robust to noise: Canny edge detection is suitable for real-world images affected by various levels of noise. The Gaussian smoothing in the initial steps makes the Canny algorithm robust to noise.

Implementation using cv2

Here is the Python code for implementing Canny edge detection using cv2:

import cv2

# Load an image
image = cv2.imread('flower.png', cv2.IMREAD_GRAYSCALE)

#create a named window to display image (optional)
cv2.namedWindow('grayscale_image')   
cv2.moveWindow('grayscale_image', 0,0)  
image_display = cv2.resize(image, (510, 510))
cv2.imshow('grayscale_image', image_display)

# Apply Canny edge detection
canny_edges = cv2.Canny(image, threshold1=150, threshold2=400)

#create another named window to display output image (optional)
cv2.namedWindow('canny_edges')   
cv2.moveWindow('canny_edges', 513,0)  
image = cv2.resize(canny_edges, (510, 510))
cv2.imshow('canny_edges', image)

#waitkey to keep display until any key entered
cv2.waitKey(0)

The provided code loads an image called the flower.png in grayscale mode from the same folder as the Python file. The grayscale image is then shown in a window using the cv2.imshow() function to view the original image. Next, the code applies the Canny edge detection algorithm to the grayscale image using the cv2.Canny(), which highlights the edges present in the image. The resulting edges are displayed in a separate window using the same visualization method. To enable observation of both the grayscale and Canny edge-detected versions, the code utilizes the cv2.waitKey to keep the display active until the user presses any key.

Conclusion

The Canny edge detection algorithm is a widely used and powerful technique for identifying edges in images. Its multistage process ensures accurate edge localization, low error rates, and robustness to noise. As technology advances, the importance of such efficient edge detection algorithms becomes increasingly evident, impacting fields like object recognition, medical imaging, surveillance, and augmented reality. The continued development and integration of the Canny algorithm into various technologies will shape the future of computer vision, enabling machines to see and interpret visual information effectively.

Free Resources

Copyright ©2024 Educative, Inc. All rights reserved