Previous portal:

“Python Image Processing OpenCV (1) : Getting Started”

“Python Image Processing OpenCV (2) : Pixel Processing with Numpy manipulation and Matplotlib Display images”

“Python Image Processing OpenCV (3) : Image Properties, ROI Regions of Interest and Channel Processing”

“Python Image Processing OpenCV (4) : Image Arithmetic and Color Space Modification”

“Python Image Processing OpenCV (5) : Geometric Transformations of Images”

“Python Image Processing OpenCV (6) : Image Threshold Processing”

“Python Image Processing OpenCV (7) : Image Smoothing (Filtering) Processing”

“Python Image Processing OpenCV (8) : Image Decay and Image Bloat”

“Python Image Processing OpenCV (9) : Image processing Morphology open, Closed, and gradient operations”

“Python Image Processing OpenCV (10) : Top hat and Black Hat Operations for Image Processing Morphology”

“Python Image Processing OpenCV (11) : Canny Operator Edge Detection

The introduction

The Canny operator edge detection was introduced in the previous section, and the Roberts operator, Prewitt operator, Sobel operator, Laplacian operator and other commonly used edge detection techniques are introduced in this section.

Roberts operator

Roberts operator, also known as Roberts operator, is one of the simplest operators, is a local difference operator to find the edge of the operator. He detected edges by approximating the gradient amplitude of the difference between two adjacent pixels in the diagonal direction. The detection effect of vertical edge is better than that of oblique edge, and the positioning accuracy is high. It is sensitive to noise and cannot suppress the influence of noise.

In 1963, Roberts proposed this edge finding operator. The Roberts edge operator is a 2×2 template that takes the difference between two adjacent pixels in the diagonal direction.

The template of Roberts operator is divided into horizontal direction and vertical direction, as shown below. From its template, it can be seen that Roberts operator can better enhance the image edge of plus or minus 45 degrees.


The calculation formula of Roberts operator in horizontal and vertical directions is as follows:



The final calculation formula of Roberts operator pixel is as follows:


Today’s formulas are elementary school level, don’t say you don’t understand.

To realize Roberts operator, we mainly use the filter2D() function in OpenCV. The main function of this function is to realize the convolution operation of images through the convolution kernel:

def filter2D(src, ddepth, kernel, dst=None, anchor=None, delta=None, borderType=None)
Copy the code
  • SRC: Enter the image
  • Ddepth: The desired depth of the target image
  • The kernel: convolution kernels

Next start to write code, the first is the image read, and the image into a gray image, this is not what to say:

# fetch image
img = cv.imread('maliao.jpg', cv.COLOR_BGR2GRAY)
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

# Grayscale image processing
grayImage = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
Copy the code

Then, Numpy is used to construct the convolution kernel, and a convolution operation is performed on the gray image in the direction of X and Y:

# Roberts operator
kernelx = np.array([[- 1.0], [0.1]], dtype=int)
kernely = np.array([[0.- 1], [1.0]], dtype=int)

x = cv.filter2D(grayImage, cv.CV_16S, kernelx)
y = cv.filter2D(grayImage, cv.CV_16S, kernely)
Copy the code

Note: After Roberts operator processing, it is also necessary to call convertScaleAbs() function to calculate the absolute value and convert the image to 8-bitmap for display before image fusion:

# turn to uint8, image fusion
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
Roberts = cv.addWeighted(absX, 0.5, absY, 0.5.0)
Copy the code

Finally, the image is displayed via Pyplot:

# Display graphics
titles = ['Original image'.'Roberts operator']
images = [rgb_img, Roberts]

for i in range(2):
    plt.subplot(1.2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()
Copy the code

The final result is as follows:

Prewitt operator

Prewitt operator is a kind of edge detection of first-order differential operator. It uses the gray difference between the upper and lower and the left and right neighboring points of pixel point to reach the extreme value of edge detection and remove part of false edge, which has smoothing effect on noise.

Prewitt operator uses 3 * 3 template to calculate pixel values in the region, while Robert operator uses 2 * 2 template, so the edge detection results of Prewitt operator are more obvious than Robert operator in both horizontal and vertical directions. Prewitt operator is suitable for recognizing images with more noise and gray gradient.

The template of the Prewitt operator is as follows:


In terms of code implementation, the implementation process of Prewitt operator and Roberts operator is similar, I will not introduce more, directly paste the code:

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

# fetch image
img = cv.imread('maliao.jpg', cv.COLOR_BGR2GRAY)
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

# Grayscale image processing
grayImage = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# Prewitt operator
kernelx = np.array([[1.1.1], [0.0.0], [- 1.- 1.- 1]],dtype=int)
kernely = np.array([[- 1.0.1], [- 1.0.1], [- 1.0.1]],dtype=int)

x = cv.filter2D(grayImage, cv.CV_16S, kernelx)
y = cv.filter2D(grayImage, cv.CV_16S, kernely)

# turn to uint8, image fusion
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
Prewitt = cv.addWeighted(absX, 0.5, absY, 0.5.0)

# used to display Chinese labels normally
plt.rcParams['font.sans-serif'] = ['SimHei']

# Display graphics
titles = ['Original image'.'Prewitt operator']
images = [rgb_img, Prewitt]

for i in range(2):
    plt.subplot(1.2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()
Copy the code

From the point of view of the result, the edge detection result of the image sharpening extracted by Prewitt operator is more obvious than that of Robert operator.

Sobel operator

Sobel operator, the Chinese name is Sobel operator, is a discrete differential operator for edge detection, which combines Gaussian smoothing and differential derivation.

Sobel operator adds the concept of weight on the basis of Prewitt operator, and thinks that the distance between adjacent points has different influence on the current pixel, and the closer the distance is, the greater the influence of the current pixel, so as to achieve image sharpening and highlight the edge contour.

The algorithm template is as follows:


Sobel operator detects the edge according to the phenomenon that the gray weighted difference between the upper and lower and the left and right adjacent points of the pixel reaches the extreme value at the edge. It has smoothing effect on noise and provides more accurate edge direction information. Because Sobel operator combines Gaussian smoothing and differential differentiation (differentiation), the results will have more anti-noise performance. When the accuracy is not very high, Sobel operator is a more commonly used edge detection method.

The formula for calculating the approximate gradient of Sobel operator is as follows:


The calculation formula of gradient direction is as follows:


If the above Angle θ equals zero, it means that the image has a vertical edge, with the left side darker than the right side.

In Python, we are provided with the Sobel() function to calculate, the overall process is similar to the previous, the code is as follows:

import cv2 as cv
import matplotlib.pyplot as plt

# fetch image
img = cv.imread('maliao.jpg', cv.COLOR_BGR2GRAY)
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

# Grayscale image processing
grayImage = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# Sobel operator
x = cv.Sobel(grayImage, cv.CV_16S, 1.0)
y = cv.Sobel(grayImage, cv.CV_16S, 0.1)

# turn to uint8, image fusion
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
Sobel = cv.addWeighted(absX, 0.5, absY, 0.5.0)

# used to display Chinese labels normally
plt.rcParams['font.sans-serif'] = ['SimHei']

# Display graphics
titles = ['Original image'.'Sobel operator']
images = [rgb_img, Sobel]

for i in range(2):
    plt.subplot(1.2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()
Copy the code

Laplacian operator

Laplacian operator is a second order differential operator in N-dimensional Euclidean space, which is often used in image enhancement and edge extraction.

The core idea of Laplacian operator is to judge the gray value of the central pixel of the image and the gray value of other pixels around it. If the gray value of the central pixel is higher, the gray value of the central pixel is improved. On the contrary, reduce the gray level of the center pixel to achieve image sharpening operation.

In the implementation process, The Laplacian operator calculates the gradient of the central pixel in the neighborhood in four or eight directions, and then adds the gradients together to judge the relationship between the gray of the central pixel and the gray of other pixels in the neighborhood. Finally, the gray of the pixel is adjusted by the results of the gradient operation.

The Laplacian operator is divided into quad-neighborhood and eight-neighborhood, where quad-neighborhood is the quad-direction gradient of the center pixel of the neighborhood, and eight-neighborhood is the eight-direction gradient.

The neighborhood template is as follows:


The neighborhood template is as follows:


Through the template, it can be found that when the gray level of pixels in the neighborhood is the same, the result of the convolution operation of the template is 0. When the gray level of the center pixel is higher than the average gray level of other pixels in the neighborhood, the result of the convolution operation of the template is positive. When the gray of the center pixel is lower than the average gray of other pixels in the neighborhood, the convolution of the template is negative. The result of convolution operation can be processed with proper weakening factor and added to the original center pixel to achieve image sharpening.

In OpenCV, Laplacian operator is encapsulated in Laplacian() function, which mainly uses the operation of Sobel operator to obtain the image sharpening result of the input image by adding the derivatives in the x and y directions of the image calculated by Sobel operator.

import cv2 as cv
import matplotlib.pyplot as plt

# fetch image
img = cv.imread('maliao.jpg', cv.COLOR_BGR2GRAY)
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

# Grayscale image processing
grayImage = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# Laplacian
dst = cv.Laplacian(grayImage, cv.CV_16S, ksize = 3)
Laplacian = cv.convertScaleAbs(dst)

# used to display Chinese labels normally
plt.rcParams['font.sans-serif'] = ['SimHei']

# Display graphics
titles = ['Original image'.'the Laplacian operator']
images = [rgb_img, Laplacian]

for i in range(2):
    plt.subplot(1.2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()
Copy the code

The last

Edge detection algorithm is mainly based on the first and second derivatives of image intensity, but the derivatives are usually sensitive to noise, so it is necessary to filter noise, and call image enhancement or thresholding algorithm for processing, and then carry out edge detection.

Finally, AFTER denoising by Gaussian filtering, EDGE detection was carried out:

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

# fetch image
img = cv.imread('maliao.jpg')
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

# Grayscale image processing
gray_image = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# Gaussian filtering
gaussian_blur = cv.GaussianBlur(gray_image, (3.3), 0)

# Roberts operator
kernelx = np.array([[- 1.0], [0.1]], dtype = int)
kernely = np.array([[0.- 1], [1.0]], dtype = int)
x = cv.filter2D(gaussian_blur, cv.CV_16S, kernelx)
y = cv.filter2D(gaussian_blur, cv.CV_16S, kernely)
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
Roberts = cv.addWeighted(absX, 0.5, absY, 0.5.0)

# Prewitt operator
kernelx = np.array([[1.1.1], [0.0.0], [- 1.- 1.- 1]], dtype=int)
kernely = np.array([[- 1.0.1], [- 1.0.1], [- 1.0.1]], dtype=int)
x = cv.filter2D(gaussian_blur, cv.CV_16S, kernelx)
y = cv.filter2D(gaussian_blur, cv.CV_16S, kernely)
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
Prewitt = cv.addWeighted(absX, 0.5, absY, 0.5.0)

# Sobel operator
x = cv.Sobel(gaussian_blur, cv.CV_16S, 1.0)
y = cv.Sobel(gaussian_blur, cv.CV_16S, 0.1)
absX = cv.convertScaleAbs(x)
absY = cv.convertScaleAbs(y)
Sobel = cv.addWeighted(absX, 0.5, absY, 0.5.0)

# Laplace algorithm
dst = cv.Laplacian(gaussian_blur, cv.CV_16S, ksize = 3)
Laplacian = cv.convertScaleAbs(dst)

# Show images
titles = ['Source Image'.'Gaussian Image'.'Roberts Image'.'Prewitt Image'.'Sobel Image'.'Laplacian Image']
images = [rgb_img, gaussian_blur, Roberts, Prewitt, Sobel, Laplacian]
for i in np.arange(6):
   plt.subplot(2.3, i+1), plt.imshow(images[i], 'gray')
   plt.title(titles[i])
   plt.xticks([]), plt.yticks([])
plt.show()
Copy the code

The sample code

If you need to get the source code, you can reply “OpenCV” on the public account to get it.

reference

Blog.csdn.net/Eastmount/a…