边缘检测算法有很多,除了在图像梯度介绍的三个算子可以用于边缘检测,这次主要介绍Canny边缘算法
步骤
-
使用高斯滤波器,以平滑图像,滤除噪声。
-
计算图像中每个像素点的梯度强度和方向。
-
应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应
-
应用双阈值(Double-Threshold)检测来确定真实和潜在的边缘
-
通过抑制孤立弱边缘最终完成边缘检测
函数公式
一、高斯滤波去噪
因为噪声点也会有梯度,所以为了减少噪点影响,应该先去噪
这边再讲一次高斯滤波,高斯滤波就是服从高斯分布矩阵的滤波矩阵,并且进行归一化处理
二、计算每个像素点的梯度和方向
算子为Sobel
三、非极大值抑制
找到局部极大值,并筛除(抑制)邻域内其余的值。
NMS算法实际上有很多,在此处仅讲解最原始的算法
- 将所有检测框按照得分从高到低排序。
- 选择得分最高的检测框并将其添加到最终检测框列表中。
- 计算该检测框与剩余检测框之间的交并比(IoU)。
- 去除与该检测框IoU值大于某个阈值的所有检测框。
- 重复步骤2-4,直到所有检测框都被处理完毕。
其中交并比(IoU)就是两个图像的交集面积和并集面积之比
具体可以查看:非极大值抑制Non-Maximum Suppression(NMS)一文搞定理论+多平台实现 - 知乎 (zhihu.com)
四、应用双阈值
大于maxval的设置为边界,
处于maxval和minval中间 和边界点相连保留,其余舍去,
小于minval 舍去
案例
def On_Track_Canny(value):
minvalue = cv2.getTrackbarPos('minvalue','Canny')
maxvalue = cv2.getTrackbarPos('maxvalue','Canny')
canny = cv2.Canny(lenaGary,minvalue,maxvalue)
cv2.imshow('Canny',canny)
minvalue = 50
maxvalue = 100
lenaGary = cv2.imread('Picture/Lena.png',cv2.IMREAD_GRAYSCALE)
cv2.namedWindow('Canny')
cv2.createTrackbar('minvalue','Canny',50,100,On_Track_Canny)
cv2.createTrackbar('maxvalue','Canny',100,300,On_Track_Canny)
cv2.setTrackbarMin('minvalue','Canny',50)
cv2.setTrackbarMin('maxvalue','Canny',100)
canny = cv2.Canny(lenaGary,minvalue,maxvalue)
cv2.imshow('Canny',canny)
cv2.waitKey(0)
cv2.destroyAllWindows()