一、原理
Canny边缘检测算法是 John F.Canny 与1986年开发出来的一个多级边缘检测算法,也被很多人认为是边缘检测的最优算法,最优边缘检测的三个主要评价标准是:
低错误率: 标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报。
高定位性: 标识出的边缘要与图像中的实际边缘尽可能接近。
最小响应: 图像中的边缘只能标识一次,同时图像噪声不应产生伪边缘。
二、步骤
1、消除噪声。使用高斯平滑滤波器卷积降噪。- GaussianBlur
2、灰度转换 - cvtColor
3、计算梯度 - Sobel / Scharr
4、非最大信号抑制。细化幅值图像中的屋脊带,即只保留幅值局部变化最大的点。
5、高低阈值输出二值图像
T1为低阈值,T2为高阈值。
a.如果某一像素位置的幅值超过T2,该像素被保留为边缘像素。
b.如果某一像素位置的幅值小于T1,该像素被丢弃。
c. 如果某一像素的位置的幅值在两个阈值之间,该像素仅仅连接到一个高于T2的像素是被保留。
最终得到一个输出二值图像
推荐的高低阈值比值为T2:T1 = 3:1 /2 : 1
三、代码
def edge_demo(img):
# 第一步 高斯模糊 去除噪声
blurred = cv.GaussianBlur(img, (3, 3), 0)
# 第二步 转成灰度图
gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)
# 第三步 计算梯度
grad_x = cv.Sobel(gray, cv.CV_16S, 1, 0)
grad_y = cv.Sobel(gray, cv.CV_16S, 0, 1)
# 第四、五步 T2:T1 = 3:1
edge_output = cv.Canny(grad_x, grad_y, 50, 150)
cv.imshow('Canny edge', edge_output)
#讲二值边缘转换成彩色边缘
dst = cv.bitwise_and(img, img, mask=edge_output)
cv.imshow('Color Edge', dst)
效果图: