Digital image processing (20): edge detection operator (the Canny operator)

Disclaimer: This article is a blogger original article, reproduced, please indicate the link. https://blog.csdn.net/zaishuiyifangxym/article/details/90142702

table of Contents

An edge detection operator Classification

2 Canny operator

2.1 Basic Theory

Code Example 2.2

3 kinds of experimental comparison operator

Reference material


The foregoing has described the  edge detection operator (Roberts operator, the Prewitt operator, Sobel operator and Laplacian operator) , will be introduced following Canny operator. Before introducing the Canny operator, or look at the edge detection operator classification.

 

An edge detection operator Classification

An edge (1) detecting a first derivative operator

Convolve each pixel and the operation as the core template image, and select the appropriate threshold to extract the edge image. Common are Roberts operator, Sobel operator and Prewitt operator.

 

Edge (2) of the second derivative operator

Based on the second derivative zero-crossing point, a common Laplacian operator, such operator is sensitive to noise.

 

(3) Canny operator

Two front edges of the image are detected by a differential operator, Canny operator there is a kind, which is derived in satisfying certain constraints to optimize edge detection operator.


 

2 Canny operator

2.1 Basic Theory

John F.Canny invention is a multi-stage edge detection algorithm --Canny edge detector 1986, and the creation of a theoretical calculation of the edge detection (Computational theory of edge detection), the theoretical effective theory explaining the operation of this technology .

Edge detection object is usually in a case where the original image retention properties, a significant reduction in the data size of the image. There are many algorithms for edge detection, Canny algorithm although the age-old, but can say it is a standard algorithm for edge detection, and is still widely used in the study.

Canny algorithm is a widely used standard edge detection algorithm, the goal is to find an optimal solution or find an edge detection image in gray scale intensity of the strongest change in the position. Optimal Edge Detection mainly by a low error rate, high positioning and minimal response were evaluated three criteria. Step Canny operator briefly as follows:

(1) denoising: applying a Gaussian filter to smooth the image, the purpose is to remove the noise

(2) Gradient: Gradient images Find

(3) non-maximal suppression: Application of non-maximum suppression to filter out non-edge pixels, fuzzy boundaries become clear. The process preserves the value of the maximum gradient strength of each pixel, filtering out other values.

Method (4) Application of double threshold to determine potential (potential) boundary;

(5) to track the boundary advantage of a hysteresis technique. If a pixel position and weak boundary connected considered strong border boundary, the other weak boundary will be deleted.

 

Canny operator specific steps are as follows:

1 to Noise

Edge detection of image noise by easily. Thus, the front edge detection is performed, usually required denoising. Typically, a Gaussian filter to remove noise, for example to a Gaussian filter kernel size of 5 \times5, a formula is as follows:

                                                                         \frac{1}{273}\times \left[ \begin{matrix} 1 & 4 & 7 & 4 & 1 \\ 4 & 16 & 26 & 16 & 4 \\ 7 & 26 & 41 & 26 & 7 \\ 4 & 16 & 26 & 16 & 4 \\ 1 & 4 & 7 & 4 & 1 \\ \end{matrix} \right]

Gauss filter for removing noise may be found blog: image smoothing (mean filter, median filter and Gaussian filtering)

 

Gradient 2: Find the image gradient

Calculating a gradient magnitude and direction in accordance with the Sobel operator, to find the gradient image. First convolution mask are acting xand Ydirection, and then calculate the gradient magnitude and direction, shown in the formula:

                                                                  {{d}_{x}}=\left[ \begin{matrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \\ \end{matrix} \right]\begin{matrix} {} & {} & {} \\ {} & {} & {} \\ {} & {} & {} \\ \end{matrix}{{d}_{y}}=\left[ \begin{matrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \\ \end{matrix} \right]

                                                                                      S=\sqrt{d_{x}^{2}+d_{y}^{2}}

                                                                                      \theta =\arctan (\frac{{{d}_{y}}}{{{d}_{x}}})

For example, the graph and the calculated gradient directions:

The general direction of the gradient is always perpendicular to the boundary, the gradient direction is classified into four types: vertical, horizontal and two diagonal lines (i.e., 0 degrees, 45 degrees, 90 degrees and 135 degrees in four directions).

 

Non-maxima suppression 3

For each pixel, it is carried out as follows: Application of non-maximum suppression to filter out non-edge pixels, fuzzy boundaries become clear. The process preserves the value of the maximum gradient strength of each pixel, filtering out other values.

1) which is approximately a gradient direction of the following values, including 0,45,90,135,180,225,270 and 315, i.e., vertical and horizontal, and represents a 45-degree direction.

2) comparing the pixel intensity of the pixel and the gradient of the gradient of its positive or negative direction, if the maximum pixel intensity gradient is retained, otherwise inhibition (deleted, i.e., set to 0).

 

 

The method of application of dual-threshold to determine the possible (potential) boundary

经过非极大抑制后图像中仍然有很多噪声点。Canny算法中应用了一种叫双阈值的技术。即设定一个阈值上界和阈值下界(opencv中通常由人为指定的),图像中的像素点如果大于阈值上界则认为必然是边界(称为强边界,strong edge),小于阈值下界则认为必然不是边界,两者之间的则认为是候选项(称为弱边界,weak edge),需进行进一步处理。过程如下图所示:

 

经过双阈值处理的图像如下图所示:

 

5 利用滞后技术来跟踪边界。若某一像素位置和强边界相连的弱边界认为是边界,其他的弱边界则被删除

最后Canny算子检测到的边缘,如下图所示:

 

2.2 代码示例

在OpenCV中,Canny() 函数用法如下所示:

edges = Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])

其中,参数:

mage 表示输入图像;

edges 表示输出的边缘图,其大小和类型与输入图像相同;

threshold1 表示第一个滞后性阈值;

threshold2 表示第二个滞后性阈值;

apertureSize 表示应用Sobel算子的孔径大小,其默认值为3;

L2gradient 表示一个计算图像梯度幅值的标识,默认值为false。

 

代码如下所示:

# -*- coding: utf-8 -*-
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
img = cv2.imread('zxp.jpg')
lenna_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 灰度化处理图像
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 高斯滤波降噪
gaussian = cv2.GaussianBlur(grayImage, (5, 5), 0)

# Canny算子
Canny = cv2.Canny(gaussian, 50, 150)

# 用来正常显示中文标签
plt.rcParams['font.sans-serif'] = ['SimHei']

# 显示图形
titles = [u'原始图像', u'Canny算子']
images = [lenna_img, Canny]
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()

 

运行结果如下图所示:

 


 

3 各类算子实验比较

Edge detection algorithm is mainly based on image intensity of a first derivative and second derivative , the derivative is usually very sensitive to noise, and therefore need a filter to filter out noise, and calls the image enhancement or thresholding algorithm treatment, and finally edge detection . The following is a (not Canny thresholding prior to detection) using Gaussian noise removal and, after thresholding, edge detection process is then performed, and the five common contrast edge detection algorithm.

 

Code as follows:

# -*- coding: utf-8 -*-
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
img = cv2.imread('zxp.jpg')
img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 转成RGB 方便后面显示

# 灰度化处理图像
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 高斯滤波
gaussianBlur = cv2.GaussianBlur(grayImage, (3, 3), 0)

# 阈值处理
ret, binary = cv2.threshold(gaussianBlur, 127, 255, cv2.THRESH_BINARY)

# Roberts算子
kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
kernely = np.array([[0, -1], [1, 0]], dtype=int)
x = cv2.filter2D(binary, cv2.CV_16S, kernelx)
y = cv2.filter2D(binary, cv2.CV_16S, kernely)
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
Roberts = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

# Prewitt算子
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 = cv2.filter2D(binary, cv2.CV_16S, kernelx)
y = cv2.filter2D(binary, cv2.CV_16S, kernely)
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
Prewitt = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

# Sobel算子
x = cv2.Sobel(binary, cv2.CV_16S, 1, 0)
y = cv2.Sobel(binary, cv2.CV_16S, 0, 1)
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

# Laplacian算子
dst = cv2.Laplacian(binary, cv2.CV_16S, ksize=3)
Laplacian = cv2.convertScaleAbs(dst)

# Canny算子
Canny = cv2.Canny(gaussianBlur, 50, 150)




# 用来正常显示中文标签
plt.rcParams['font.sans-serif'] = ['SimHei']

# # 显示图形
plt.subplot(231), plt.imshow(img_RGB), plt.title('原始图像'), plt.axis('off')  # 坐标轴关闭
plt.subplot(232), plt.imshow(Canny, cmap=plt.cm.gray), plt.title('Canny算子'), plt.axis('off')
plt.subplot(233), plt.imshow(Roberts, cmap=plt.cm.gray), plt.title('Roberts算子'), plt.axis('off')
plt.subplot(234), plt.imshow(Prewitt, cmap=plt.cm.gray), plt.title('Prewitt算子'), plt.axis('off')
plt.subplot(235), plt.imshow(Sobel, cmap=plt.cm.gray), plt.title('Sobel算子'), plt.axis('off')
plt.subplot(236), plt.imshow(Laplacian, cmap=plt.cm.gray), plt.title('Laplacian算子'), plt.axis('off')

plt.show()

 

Operating results as shown below:

 

Multi-test several images to see results

 

 


 

Reference material

[1] https://blog.csdn.net/Eastmount/article/details/89056240

[2]  the Python image processing the OpenCV +

[3]  Gonzalez. Digital Image Processing (third edition) 

Guess you like

Origin blog.csdn.net/zaishuiyifangxym/article/details/90142702