文章目录
- 0. 前言
- 1. Sobel算子
- 2. Canny算子
- 3. 深度学习算法
- 3.1 Holistically-Nested Edge Detection(HED)
- 3.2 Richer Convolutional Features(RCF)
0. 前言
边缘检测是一种图像处理技术,旨在标识和定位数字图像中的边缘和轮廓。边缘是图像中灰度值变化明显的位置,通常是物体的边缘或表面的变化。通过边缘检测算法,可以将图像中的物体和背景分离出来,从而实现目标检测、图像分割、计算机视觉和机器人视觉等应用。
边缘检测算法的基本原理是在数字图像中寻找灰度变化的位置。其中,最常见的方法是基于图像梯度的边缘检测算法,如Sobel算子、Prewitt算子、Roberts算子和Canny算子等。
1. Sobel算子
Sobel算子将数字图像与两个卷积核Gx和Gy进行卷积,Gx和Gy分别用于计算水平方向和垂直方向上的梯度:
G
x
=
[
−
1
0
1
−
2
0
2
−
1
0
1
]
G_x = \begin{bmatrix}-1 & 0 & 1 \\-2 & 0 & 2 \\-1 & 0 & 1\end{bmatrix}
Gx=
−1−2−1000121
G
y
=
[
−
1
−
2
−
1
0
0
0
1
2
1
]
G_y = \begin{bmatrix}-1 & -2 & -1 \\0 & 0 & 0 \\1 & 2 & 1\end{bmatrix}
Gy=
−101−202−101
在计算完Gx和Gy之后,可以计算每个像素的梯度强度和方向:
G
=
G
x
2
+
G
y
2
G = \sqrt{G_x^2 + G_y^2}
G=Gx2+Gy2
θ
=
tan
−
1
(
G
y
G
x
)
\theta = \tan^{-1}\left(\frac{G_y}{G_x}\right)
θ=tan−1(GxGy)
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图片
img = cv2.imread("example.jpg", cv2.IMREAD_GRAYSCALE)
# 定义Sobel算子
sobel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
sobel_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])
# 对图片进行Sobel边缘检测
img_sobel_x = cv2.filter2D(img, -1, sobel_x)
img_sobel_y = cv2.filter2D(img, -1, sobel_y)
# 计算梯度幅值和梯度方向
gradient_magnitude = np.sqrt(img_sobel_x ** 2 + img_sobel_y ** 2)
gradient_magnitude = (gradient_magnitude / gradient_magnitude.max())*255
gradient_direction = np.arctan2(img_sobel_y, img_sobel_x)
gradient_direction = (gradient_direction / gradient_direction.max()) * 255
# 显示结果
fig, axs = plt.subplots(1, 4, figsize=(16, 4))
axs[0].imshow(img, cmap="gray")
axs[0].set_title("Original")
axs[1].imshow(img_sobel_x, cmap="gray")
axs[1].set_title("Sobel X")
axs[2].imshow(img_sobel_y, cmap="gray")
axs[2].set_title("Sobel Y")
axs[3].imshow(gradient_magnitude.astype(np.uint8), cmap="gray")
axs[3].set_title("Gradient Magnitude")
plt.show()
可以看到,Gx主要检测出了竖直方向上的边缘,Gy主要检测出了水平方向上的边缘。
2. Canny算子
Canny算子是在工业界广泛使用的边缘检测算法,它的主要原理是通过检测图像中像素灰度变化的一阶导数来检测边缘。
Canny算法主要分为以下几个步骤:
-
去噪
由于图像中可能存在噪声,并且噪声对边缘检测的影响较大(因为噪声也是高频信息),首先需要对图像进行去噪声处理。常见的方法是使用高斯滤波器对图像进行平滑处理,以减少噪声的影响。 -
计算梯度
在图像平滑之后,需要计算每个像素点的梯度值和方向。常用的方法是使用Sobel算子,对图像进行水平和垂直方向上的梯度计算。梯度方向的计算可以通过计算水平和垂直梯度值的反正切来得到。 -
非极大值抑制
由于Sobel算子计算的梯度值较大,图像中可能存在多个方向的梯度,需要进行非极大值抑制来确定每个像素点的主要梯度方向。具体来说,对于每个像素点,沿着其梯度方向上的两个邻域像素点进行比较,如果当前像素点的梯度值最大,则保留它,否则将其置为零。 -
双阈值检测
经过前面的处理之后,图像中只剩下边缘可能存在的位置。但是,由于图像中存在很多噪声和灰度变化,有些边缘可能会被误判为非边缘。因此需要使用双阈值检测来进一步筛选边缘。将梯度幅值分为两个阈值:高阈值和低阈值。如果一个像素点的梯度幅值大于高阈值,则被认为是边缘像素;如果一个像素点的梯度幅值小于低阈值,则被认为是非边缘像素。如果一个像素点的梯度幅值在两个阈值之间,则只有它与高阈值相连的像素点才被认为是边缘像素。 -
边缘连接
经过上述处理之后,图像中可能还存在一些不连续的边缘。因此,需要使用边缘连接算法将它们连接起来。一种常用的方法是使用基于滞后阈值的连接算法。具体来说,从高阈值像素开始,将与其相邻的低阈值像素加入到边缘中,直到不存在低阈。
3. 深度学习算法
3.1 Holistically-Nested Edge Detection(HED)
HED是一个端到端的边缘检测模型,总体架构如下:
3.2 Richer Convolutional Features(RCF)
RCF是针对HED的改进