一、概念
Canny边缘检测算法是John F.Canny与1986年开发出来的一个多级边缘检测算法,也被很多人认为是边缘检测的最优算法。最优边缘检测的三个主要评价标准是:
低错频率:表示出尽可能多的实际边缘,同时尽可能的减小噪声产生的误报。
高定位性:标识出的边缘要与图像中的实际边缘尽可能接近。
最小响应:图像中的边缘只能标识一次。
Canny边缘检测的一般步骤:
1)去噪。边缘检测容易受到噪声干扰,在进行边缘检测前通常需要先进行去噪,一般用高斯滤波去除噪声。
2)计算梯度:对平滑后的图像采样sobel算子计算梯度和方向.
为了方便一般可以改用绝对值。 ——计算出梯度
——计算出角度,从而得到方向
梯度的方向被归为四类:垂直、水平和两个对角线
计算出来的梯度和方向大概如下图:
相当于将一个圆形平分为八块,即共有八个方向。
3)非极大值抑制(NMS)
— 在获取了梯度和方向后,遍历图像,去掉所有不是边界的点(归零)。
— 实现方法:逐个遍历像素点,判断当前像素点是否是周围像素点中具有相同方向梯度的最大值。(边缘上的点梯度值最大)
— 下图中,点A,B,C具有相同的方向,梯度方向垂直于边缘。
— 判断点A是否为A,B,C中的局部最大值,如果是,保留该点;否则,它被抑制(归零)
更形象的例子:
4) 滞后阈值
如果梯度值位于最大值和最小值之间,则如果与边界外点相连,则该点保留;如果与边界不相连,则抛弃。
二、在OpenCV中的使用
使用API---Canny(img, minVal,maxVal)
需要注意:阈值越小,细节越丰富。
示例代码如下:
import cv2
import numpy as np
img = cv2.imread("beautiful women.png")
# 阈值较大,则细节不明显
lena1 = cv2.Canny(img, 100, 200)
# 阈值较小,细节更明显
lena2 = cv2.Canny(img, 64, 128)
cv2.imshow("lena", np.hstack((lena1, lena2)))
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果如下:
可以看出,右边的细节更明显,因为设置的阈值范围更小。