OpenCV 08 (image filter operator)

1. Sobel operator

The edge is the position where the pixel value transitions. It is one of the salient features of the image and plays an important role in image feature extraction, object detection, pattern recognition, etc.

How does the human eye identify image edges?

For example, if there is a picture, there is a line in the picture, the left side is very bright, and the right side is very dark, then the human eye can easily identify this line as an edge. This is where the gray value of the pixel changes rapidly .

The sobel operator takes the first derivative of the image . The larger the first-order derivative is, the greater the change of the pixel in that direction is and the stronger the edge signal is.

Because the grayscale values ​​of the image are all discrete numbers, the sobel operator uses the discrete difference operator to calculate the approximate gradient of the brightness value of the image pixel point.

The image is two-dimensional, that is, along the width/height directions.
We use two convolution kernels to process the original image:

- horizontal direction

- Vertical direction

In this case, we get two new matrices, which respectively reflect the brightness change of each pixel in the horizontal direction and the brightness transformation in the vertical direction.

**Considering the changes in these two directions**, we use the following formula to reflect the gradient change of a certain pixel.

Sometimes for the sake of simplicity, absolute value addition is used instead.

# 索贝尔算子.
import cv2
import numpy as np


#导入图片
img = cv2.imread('./chess.png')#
# x轴方向, 获取的是垂直边缘
dx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=5)
dy = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=5)

# 可利用numpy的加法, 直接整合两张图片
# dst = dx + dy
# 也可利用opencv的加法
dst = cv2.add(dx, dy)
cv2.imshow('dx', np.hstack((dx, dy, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

2. Scharr operator

- Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]]) - When the
kernel size is 3, the above Sobel kernel may produce obvious errors (the Sobel operator is just for Taking the approximate value of the derivative ). To solve this problem, OpenCV provides the Scharr function, but this function only works on kernels of size 3 . This function operates as fast as the Sobel function, but the results are more accurate.

- The Scharr operator is very similar to Sobel, but uses different kernel values ​​to amplify the pixel transformation :

- Scharr operator only supports 3 * 3 kernel, so there is no kernel parameter.

- The Scharr operator can only find edges in the x direction or y direction.

- Setting the ksize of the Sobel operator to -1 is the Scharr operator. 

- Scharr is good at finding small edges and is generally used less often.

# 索贝尔算子.
import cv2
import numpy as np


#导入图片
img = cv2.imread('./lena.png')#
# x轴方向, 获取的是垂直边缘
dx = cv2.Scharr(img, cv2.CV_64F, 1, 0)
# y轴方向, 获取的是水平边缘
dy = cv2.Scharr(img, cv2.CV_64F, 0, 1)

# 可利用numpy的加法, 直接整合两张图片
# dst = dx + dy
# 也可利用opencv的加法
dst = cv2.add(dx, dy)
cv2.imshow('dx', np.hstack((dx, dy, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

3. Laplacian operator

The Sobel operator simulates first-order derivation. The larger the derivative, the more severe the transformation and the more likely it is an edge.

What if we continue to derive the derivative of f'(t)?

It can be found that the second-order derivative = 0 "at the edge", we can use this feature to find the edge of the image. ** Note that there is a problem, the position where the second-order derivative is 0 may also be a meaningless position **.

- **Laplacian operator derivation process**

- Take the solution in the x direction as an example:
    first-order difference: f'(x) = f(x) - f(x - 1)
    second-order difference: f''(x) = f'(x+1) - f' (x) = (f(x + 1) - f(x)) - (f(x) - f(x - 1))
    After simplification: f''(x) = f(x - 1) - 2 f(x)) + f(x + 1)

    In the same way, we can get: f''(y) = f(y - 1) - 2 f(y)) + f(y + 1)

    Stack the gradients in the x and y directions together.

    $f''(x,y) = f''_x(x,y) + f''_y(x,y)$

    $f''(x,y) = f(x - 1, y) - 2 f(x,y)) + f(x + 1, y) + f(x, y - 1) - 2 f(x,y)) + f(x,y + 1)$

    $f''(x,y) = f(x - 1, y) + f(x + 1, y) + f(x, y - 1) + f(x,y + 1) - 4 f(x,y)) $

This equation can be written as a matrix:

In this way, the convolution kernel of the Laplacian operator, that is, the convolution template is obtained.

 

- Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])

-Can find edges in two directions at the same time
-Sensitive to noise, generally need to denoise first and then call Laplacian

# 拉普拉斯
import cv2
import numpy as np


#导入图片
img = cv2.imread('./chess.png')#
dst = cv2.Laplacian(img, -1, ksize=3)

cv2.imshow('dx', np.hstack((img, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()

Generally, it is converted into a grayscale image, and then the edges are found.

4. Edge detection Canny

*Canny edge detection algorithm* is a multi-level edge detection algorithm developed by John F. Canny in 1986. It is also considered by many to be the *optimal algorithm* for edge detection. The three main evaluation criteria for optimal edge detection are :

> - **Low Error Rate:** Identify as many actual edges as possible while minimizing false positives caused by noise.
> - **High localization:** The identified edges should be as close as possible to the actual edges in the image.
> - **MINIMUM RESPONSE:** Edges in the image can only be identified once.

- General steps for Canny edge detection

  •  Denoising. Edge detection is easily affected by noise. Denoising is usually required before edge detection. Gaussian filtering is generally used to remove noise .
  •  Calculate the gradient: Use the sobel operator to calculate the gradient and direction of the smoothed image.

  •   The directions of gradients are classified into four categories: vertical, horizontal and two diagonals.
  •   The calculated gradient and direction are roughly as shown below:

  • non-maximum suppression

    - After obtaining the gradient and direction, traverse the image and remove all points that are not boundaries.

    - Implementation method: Traverse pixels one by one to determine whether the current pixel is the maximum value of the surrounding pixels with the same direction gradient.

    - In the figure below, points A, B, and C have the same direction, and the gradient direction is perpendicular to the edge.

    - Determine whether point A is the local maximum among A, B, and C. If so, retain the point; otherwise, it is suppressed (reset to zero)

    - A more vivid example:

 

  • hysteresis threshold

Canny(img, minVal, maxVal, ...)

# Canny
import cv2
import numpy as np


#导入图片
img = cv2.imread('./lena.png')#
# 阈值越小, 细节越丰富
lena1 = cv2.Canny(img, 100, 200)
lena2 = cv2.Canny(img, 64, 128)

cv2.imshow('lena', np.hstack((lena1, lena2)))
cv2.waitKey(0)
cv2.destroyAllWindows()

Guess you like

Origin blog.csdn.net/peng_258/article/details/132774054