8. Opencv-python advanced image processing operations (5) - edge detection

  • Edge detection is often regarded as a master's degree topic or a company interview question, so it is very important. In this chapter, several common edge detection operators will be introduced.

learning target

Understand the Sobel operator, Scharr operator and Laplacian operator

Master the principles and applications of canny edge detection

1. Principle of edge detection

Edge detection is a fundamental problem in image processing and computer vision, and its purpose is to represent points in digital images with obvious brightness changes. Significant changes in image attributes often reflect important events and changes in the attributes. The expression of edge detection is shown in the figure below:
Insert image description here
Image edge detection greatly reduces the amount of data, removes information that can be considered irrelevant, and retains important structural attributes of the image. There are many methods for edge detection, most of which can be divided into two categories: search-based and zero-crossing-based.

1. Based on search

The boundary is detected by finding the maximum value in the first derivative of the image, and then using the calculation results to estimate the local direction of the edge. Usually the direction of the gradient is used, and this direction is used to find the maximum value of the local gradient module. Representative algorithms include Sobel operator and Scharr operator.

(1) The maximum value of the first derivative of the image -->
.
(2) The local direction of the edge (general gradient direction) -->
.
(3) The maximum value of the local gradient module

Insert image description here

2. Based on zero crossing

The boundary is found by looking for the zero crossing of the second derivative of the image, and the representative operator is the laplacian operator.
The zero point is the intersection of the function and the y-axis.
Insert image description here

2. Sobel detection operator

The Sobel edge detection algorithm is relatively simple and is more efficient than canny edge detection in practical applications . However, the edge is not as accurate as canny detection, but in many practical applications, the Sobel operator is the first choice.
The Sobel operator is a combination of Gaussian smoothing and differential operations, so it has strong noise resistance and many uses . Especially when efficiency requirements are high and you don't care much about detailed textures.

1. Discussion of principles and methods

For discontinuous functions, the first derivative can be written as:
Insert image description here
or
Insert image description here
So there is:
Insert image description here
Assume that the image to be processed is I, and the derivative is taken in two directions

  • Horizontal change: Convolve the image I with a template of period size, and the result is Gx. For example, when the template size is 3, Gx is:
    Insert image description here
  • Vertical variation: Convolve the image I with a template of technical size, the result is Gy. For example, when the template size is 3, Gy is:
    Insert image description here
    At each point of the image, combined with the above two results,
    Insert image description here
    the position of the statistical maximum value is the edge of the image.
    **Note:** When the kernel size is 3, the above Sobel kernel may produce obvious errors. To solve this problem, we use the Scharr function, but this function only works on kernels with a size of 3. This function operates as fast as the Sobel function, but the results are more accurate. It is calculated as:
    Insert image description here

2. Application

The API for Sobel edge detection using OpenCV is:

Sobel_x_or_y = 
cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)

parameter:

  • src: the incoming image
  • ddepth: the depth of the image
  • dx and dy: refer to the order of derivation, 0 means there is no derivation in this direction, and the values ​​are 0 and 1.
  • ksize: is the size of the Sobel operator, that is, the size of the convolution kernel. It must be an odd number of 1, 3, 5, or 7, and the default is 3.
  • Note: If ksize=-1, it evolves into a 3x3 Scharr operator.
  • scale: The proportional constant of the scaling derivative, the default is no scaling coefficient.
  • borderType: The mode of the image border, the default value is cv2.BORDER_DEFAULT.

After the Sobel function calculates the derivative, there will be negative values ​​and there will be values ​​greater than 255. The original image is uint8, that is, 8 is an unsigned number, so the image created by Sobel does not have enough digits and will be truncated. Therefore use the 16-bit signed data type, cv2.CV_16s. After processing the image, use the cv2.convertScaleAbs() function to convert it back to the original uint8 type, otherwise the image cannot be displayed.

The Sobel operator is calculated in two directions, and finally needs to be combined using the cv2.addWeighted() function

Scale_abs = cv2.convertScaleAbs(x)  # 格式转换函数
result = cv2.addWeighted(src1, alpha, src2, beta) # 图像混合

Code example:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# 1 读取图像
img = cv.imread('./image/horse.jpg',0)
# 2 计算Sobel卷积结果
x = cv.Sobel(img, cv.CV_16S, 1, 0)
y = cv.Sobel(img, cv.CV_16S, 0, 1)
# 3 将数据进行转换
Scale_absX = cv.convertScaleAbs(x)  # convert 转换  scale 缩放
Scale_absY = cv.convertScaleAbs(y)
# 4 结果合成
result = cv.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)
# 5 图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原图')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(result,cmap = plt.cm.gray),plt.title('Sobel滤波后结果')
plt.xticks([]), plt.yticks([])
plt.show()

Insert image description here
Set the ksize of the Sobel operator calculation part in the above code to -1, which is to use scharr for edge detection.

x = cv2.Sobel(img, cv2.CV_16S, 1, 0, ksize=-1)
y = cv2.Sobel(img, cv2.CV_16S, 0, 1, ksize=-1)

Insert image description here

It can be seen that using Scharr operator, the detection effect is slightly better than Sobel operator.

3. Laplacian operator

The Laplacian detection method uses second-order derivatives to detect edges. Because the image is "2-dimensional", we need to derive the derivative in two directions, as shown in the following formula:
Insert image description here
Then the discontinuous second-order derivative is:
Insert image description here
Then the convolution kernel used is:
Insert image description here
API:

laplacian = cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])

parameter:

  • Src: image
  • Ddepth: Image depth, -1 means the same depth of the original image is used, and the depth of the target image must be greater than or equal to the depth of the original image;
  • ksize: The size of the operator, that is, the size of the convolution kernel, must be 1, 3, 5, 7

Code example:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# 1 读取图像
img = cv.imread('./image/horse.jpg',0)
# 2 laplacian转换
result = cv.Laplacian(img,cv.CV_16S)
Scale_abs = cv.convertScaleAbs(result)
# 3 图像展示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原图')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(Scale_abs,cmap = plt.cm.gray),plt.title('Laplacian检测后结果')
plt.xticks([]), plt.yticks([])
plt.show()

Insert image description here

4. canny edge detection

The canny edge detection algorithm is a very popular edge detection algorithm. It was proposed by John F. Canny in 1986 and is considered to be the best edge detection algorithm.

1. Principle of Canny algorithm

The Canny edge detection algorithm consists of 4 steps, which are introduced as follows:

  • noise removal

Since edge detection is easily interfered by noise, a Gaussian filter is first used to remove the noise. (Gaussian filtering is mentioned in Image Smoothing, you can read forward)

  • Calculate image gradient

Use the Sobel operator to calculate the first derivatives (Gx and Gy) in the horizontal and vertical directions of the smoothed image . Find the gradient and direction of the boundary based on the two obtained gradient maps (Gx and Gy). The formula is as follows:
Insert image description here
If a pixel is an edge, its gradient direction is always perpendicular to the edge direction. Gradient directions are classified into four categories: vertical, horizontal, and two diagonal directions.

  • non-maximum suppression

After obtaining the gradient direction and magnitude, scan the entire image to remove points that are not on the boundary. Check each pixel to see if the gradient of this point is the largest among surrounding points with the same gradient direction. As shown in the figure below:
Insert image description here
Point A is located at the edge of the image. In the direction of its gradient change, select pixel points B and C to check whether the gradient of point A is a maximum value. If it is a maximum value, keep it, otherwise A Points are suppressed and the end result is a binary image with "thin edges".

  • hysteresis threshold

Now comes the determination of the true boundaries. We set two thresholds: minVal and maxVal. When the gray gradient of the image is higher than maxVal, it is considered to be a true boundary, and the boundary below minVal will be discarded. If it is between the two, it depends on whether the point is connected to a certain boundary point determined to be a real boundary point. If so, it is considered to be a boundary point. If not, it is discarded. As shown in the figure below:
Insert image description here
As shown in the figure above, A is higher than the threshold maxVal, so it is a real boundary point. Although C is lower than maxVal, it is higher than minVal and is connected to A, so it is also considered a real boundary point. And B will be discarded because it is lower than maxVal and not connected to the real boundary point. So choosing appropriate maxVal and minVal is very important to get good results.

2. Application

API used to implement canny detection in opencv Chinese Medicine:

canny = cv2.Canny(image, threshold1, threshold2)

parameter:

  • image: grayscale image,
  • threshold1: minval, a smaller threshold connects discontinuous edges
  • threshold2: maxval, a larger threshold to detect obvious edges in the image
    . Code example:
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# 1 图像读取
img = cv.imread('./image/horse.jpg',0)
# 2 Canny边缘检测
lowThreshold = 0
max_lowThreshold = 100
canny = cv.Canny(img, lowThreshold, max_lowThreshold) 
# 3 图像展示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原图')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(canny,cmap = plt.cm.gray),plt.title('Canny检测后结果')
plt.xticks([]), plt.yticks([])
plt.show()

Insert image description here

Summarize:

1. Principle of edge detection

(1) Based on search

(2) Based on zero crossing

2. Sobel operator [Practical application]

(1) Obtain the boundary based on search method

(2)cv2.Sobel()

(3)cv2.convertScaleAbs()

(4)cv2.addWeighted()

3. Laplacian operator

(1) Obtain the boundary based on zero crossing

(2)cv2.Laplacian()

4. Canny algorithm

(1) Noise removal (Gaussian filtering)

(2) Calculate image gradient (Sobel operator)

(3) Non-maximum suppression: Determine whether the pixel is a boundary point

(4) Hysteresis threshold: Set two thresholds to determine the final boundary

5. Comparison between various traditional operators

Insert image description here

  • The road to becoming stronger is long and arduous, so come on! ! !

Guess you like

Origin blog.csdn.net/weixin_44463519/article/details/126095174