Canny 边缘检测算法由计算机科学家 John F. Canny 于 1986 年提出的。其不仅提供了算法,还带来了一套边缘检测的理论,分阶段的解释如何实现边缘检测。Canny 检测算法包含下面几个阶段:
灰度化
高斯模糊
计算图片梯度幅值
非极大值抑制
双阈值选取
灰度化
灰度化实际上是一种降维的操作,可以减少计算。如果算法不进行色彩相关的识别的话,不灰度化,也可以直接进行后面的阶段。
# 灰度化
def gray(self, img_path):
"""
计算公式:
Gray(i,j) = [R(i,j) + G(i,j) + B(i,j)] / 3
or :
Gray(i,j) = 0.299 * R(i,j) + 0.587 * G(i,j) + 0.114 * B(i,j)
"""
# 读取图片
img = plt.imread(img_path)
# BGR 转换成 RGB 格式
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 灰度化
img_gray = np.dot(img_rgb[...,:3], [0.299, 0.587, 0.114])
return img_gray
高斯模糊
在实际的图片中,都会包含噪声。但有时候,图片中的噪声会导致图片中边缘信息的消失。对此的解决方案就是使用高斯平滑来减少噪声,即进行高斯模糊操作。该操作是一种滤波操作,与高斯分布有关,下面是一个二维的高斯函数,其中 (x, y) 为坐标,σ 为标准差:
进行高斯滤波之前,需要先得到一个高斯滤波器(kernel)。如何得到一个高斯滤波器?其实就是将高斯函数离散化,将滤波器中对应的横纵坐标索引代入高斯函数,即可得到对应的值。不同尺寸的滤波器,得到的值也不同,下面是 (2k+1)x(2k+1) 滤波器的计算公式 :
常用尺寸为 5x5,σ=1.4 的高斯滤波器。下面是 5x5 高斯滤波器的实现代码:
# 去除噪音 - 使用 5x5 的高斯滤波器
def smooth(self, img_gray):
# 生成高斯滤波器
"""
要生成一个 (2k+1)x(2k+1) 的高斯滤波器,滤波器的各个元素计算公式如下:
H[i, j] = (1/(2*pi*sigma**2))*exp(-1/2*sigma**2((i-k-1)**2 + (j-k-1)**2))
"""
sigma1 = sigma2 = 1.4
gau_sum = 0
gaussian = np.zeros([5, 5])
for i in range(5):
for j in range(5):
gaus