Image processing in OpenCV 007_Canny edge detection

The main content of this article comes from the image processing part of OpenCV in the OpenCV-Python tutorial . The main content of this part is as follows:

Target

In this chapter we will learn about

  • The concept of Canny edge detection
  • Function provided for this in OpenCV: cv.Canny()

theory

Canny edge detection is a popular edge detection algorithm. It was developed by John F. Canny

  1. This is a multi-stage algorithm and we will go through each stage.
  2. Noise Reduction
    Since edge detection is susceptible to noise in the image, the first step is to use a 5x5 Gaussian filter to remove the noise in the image. We have seen this in previous chapters.
  3. Find the intensity gradient of the image
    and then filter the smoothed image using the Sobel kernel in the horizontal and vertical directions to obtain the horizontal direction ( G x G_xGx) and vertical direction ( G y G_yGy) first derivative. From these two images, we can find the edge gradient and direction of each pixel as follows:
    E dge _ G radient ( G ) = G x 2 + G y 2 A ngle ( θ ) = tan ⁡ − 1 ( G y G x ) Edge\_Gradient \; (G) = \sqrt{G_x^2 + G_y^2} \\ Angle \; (\theta) = \tan^{-1} \bigg(\frac{G_y} {G_x}\bigg)Edge_Gradient(G)=Gx2+Gy2 Angle( i )=tan1(GxGy)
    gradient direction is always perpendicular to the edge. It is rounded to one of four angles representing vertical, horizontal, and two diagonal directions.
  4. Non-maximum suppression
    After obtaining the gradient magnitude and direction, a full scan of the image is performed to remove any unwanted pixels that may not constitute an edge. To do this, at each pixel, it is checked whether the pixel is a local maximum in its neighborhood along the gradient direction. Check the image below:
    image
    Point A is on the edge (vertical direction). The gradient direction is perpendicular to the edge. Points B and C are in the gradient direction. So point A is checked together with points B and C to see if it is a local maximum. If it is, it will be considered for the next stage, otherwise, it will be suppressed (zeroed).
    In short, the result we get is a binary image with "thin edges".
  5. Hysteresis Threshold
    This stage determines which all edges are real edges and which are not. For this we need two thresholds, minValand maxVal. Any maxValedge with an intensity gradient greater than is definitely an edge, and any minValedge with an intensity gradient below is definitely a non-edge and therefore discarded. Those lying between these two thresholds are classified as edge or non-edge based on their connectivity. If they are connected to "definite edge" pixels, they are considered part of the edge. Otherwise, they are also discarded. See the image below:
    image
    Edge A is maxValabove and therefore considered a "definite edge". Even though edge C is maxValbelow , it is connected to edge A and is therefore considered a valid edge, and we get the complete curve. But edge B, even though it is minValabove and in the same area as edge C, is not connected to any "definite edge", so it is discarded. minValTherefore, it is very important that we choose and accordingly maxValto get the correct results.
    This stage also removes small pixel noise under the assumption that edges are long lines.

So what we end up with are strong edges in the image.

Canny edge detection in OpenCV

OpenCV puts all of the above into one function, cv.Canny() . We'll see how to use it. The first parameter is our input image. The second and third parameters are our minValand respectively maxVal. The fourth parameter is aperture_size. It is the size of the Sobel kernel used to find the gradient of the image. Its default is 3. The last parameter is L2gradient, which specifies the equation for finding the gradient magnitude. If it is True, it uses the more precise equation mentioned above, otherwise it uses this function: E dge _ G radient ( G ) = ∣ G x ∣ + ∣ G y ∣ Edge\_Gradient \; (G) = |G_x | + |G_y|Edge_Gradient(G)=Gx+Gy . Its default value isFalse.

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt


def canary_edge_detection():
    cv.samples.addSamplesDataSearchPath("/media/data/my_multimedia/opencv-4.x/samples/data")
    img = cv.imread(cv.samples.findFile('messi5.jpg'))
    edges = cv.Canny(img, 100, 200)
    plt.subplot(121), plt.imshow(img, cmap='gray')
    plt.title('Original Image'), plt.xticks([]), plt.yticks([])
    plt.subplot(122), plt.imshow(edges, cmap='gray')
    plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
    plt.show()


if __name__ == "__main__":
    canary_edge_detection()

Let’s look at the following results:
image

Other resources

  1. Canny edge detection in Wikipedia

  2. Canny edge detection tutorial  by Bill Green, 2002.

practise

Write a small application to find Canny edge detection, the threshold of which can be changed using the two track bars. This way, you can understand the impact of the threshold.

Reference documentation

Canny Edge Detection

Done.

Guess you like

Origin blog.csdn.net/tq08g2z/article/details/125119148