Open CV系列学习笔记(十六)Canny边缘提取
Canny算法
Canny边缘检测算子是John F. Canny于 1986 年开发出来的一个多级边缘检测算法。更为重要的是 Canny 创立了边缘检测计算理论(Computational theory of edge detection)解释这项技术如何工作。
通常情况下边缘检测的目的是在保留原有图像属性的情况下,显著减少图像的数据规模。有多种算法可以进行边缘检测,虽然Canny算法年代久远,但可以说它是边缘检测的一种标准算法,而且仍在研究中广泛使用。
Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是:
(1)最优检测:算法能够尽可能多地标识出图像中的实际边缘,漏检真实边缘的概率和误检非边缘的概率都尽可能小;
(2)最优定位准则:检测到的边缘点的位置距离实际边缘点的位置最近,或者是由于噪声影响引起检测出的边缘偏离物体的真实边缘的程度最小;
(3)检测点与边缘点一一对应:算子检测的边缘点与实际边缘点应该是一一对应。
为了满足这些要求 Canny 使用了变分法(calculus of variations),这是一种寻找优化特定功能的函数的方法。最优检测使用四个指数函数项表示,但是它非常近似于高斯函数的一阶导数。
- 高斯模糊 - GaussianBlur
- 灰度转换 - cvtColor
- 计算梯度 – Sobel/Scharr
- 非最大信号抑制
- 高低阈值输出二值图像
.高低阈值的连接
T1, T2为阈值,凡是高于T2的都保留,凡是小于
T1都丢弃,从高于T2的像素出发,凡是大于T1而
且相互连接的,都保留。最终得到一个输出二值图
像。
推荐的高低阈值比值为 T2: T1 = 3:1/2:1其中T2
为高阈值, T1为低阈值
代码:
def edge_demo(image):#Canny边缘提取
blurred = cv.GaussianBlur(image,(3,3),0)#高斯模糊
gray = cv.cvtColor(blurred,cv.COLOR_BGR2GRAY)#灰度转化
# X 方向的梯度
xgrad = cv.Sobel(gray,cv.CV_16SC1,1,0)
# Y 方向的梯度
ygrad = cv.Sobel(gray,cv.CV_16SC1,0,1)
#边缘
#edge_output = cv.Canny(xgrad,ygrad,50,150)
edge_output = cv.Canny(gray,50,150)#高低阈值比值2:1到3:1之间
cv.imshow("Canny Edge",edge_output)
dst = cv.bitwise_and(image,image,mask = edge_output)#彩色边缘
cv.imshow("Color Edge",dst)
结果:
完整代码:
import cv2 as cv
import numpy as np
def edge_demo(image):#Canny边缘提取
blurred = cv.GaussianBlur(image,(3,3),0)#高斯模糊
gray = cv.cvtColor(blurred,cv.COLOR_BGR2GRAY)#灰度转化
# X 方向的梯度
xgrad = cv.Sobel(gray,cv.CV_16SC1,1,0)
# Y 方向的梯度
ygrad = cv.Sobel(gray,cv.CV_16SC1,0,1)
#边缘
#edge_output = cv.Canny(xgrad,ygrad,50,150)
edge_output = cv.Canny(gray,50,150)#高低阈值比值2:1到3:1之间
cv.imshow("Canny Edge",edge_output)
dst = cv.bitwise_and(image,image,mask = edge_output)#彩色边缘
cv.imshow("Color Edge",dst)
print("--------HEllow Python-------")
src = cv.imread("E:/picture/10.bmp")
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow("input image",src)
edge_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()