- 1.Canny引入
- 2.Canny算法实现步骤
- (1)去噪
- (2)计算梯度和梯度方向
- (3)过滤非最大值
- (4)使用阈值检测边缘
- 3.Canny函数实现
- 4.实例代码测试
- (1)图片测试代码
- (1)调节阈值大小
- (2)使用L2gradient=True
- (3)设置apertureSize中的Sobel算子大小
- (2)实时检测代码
- 5.Canny的实际应用
(1)Canny边缘检测算子是John.F.Canny与1986年开发出来的一个多级边缘检测算法;边缘检测是计算机视觉中一个非常古老的问题,它涉及到检测图像中的边缘来确定目标的边界,从而分离感兴趣的目标。最流行的边缘检测技术之一是Canny边缘检测。
(2)对最优边缘检测算法评价
a.好的检测:算法能够尽可能多的标识出图片中的实际边缘;
b.好的定位:标识出的边缘要与实际图片中的实际边缘尽可能的接近;
c.最小响应:图像中的边缘只能标识一次,并且可能存在的图像噪声不应该标识为边缘。
https://wenku.baidu.com/view/54a32be6d6bbfd0a79563c1ec5da50e2524dd1da.html
2.Canny算法实现步骤 (1)去噪
:因为原始的图片具有很多随机的噪声,那么在进行边缘处理的时候很容易将这些噪声视为图像的边缘,可以使用5x5的高斯滤波器对图像进行平滑(模糊)。
(2)计算梯度和梯度方向:使用4个mask检测水平,垂直以及对角线方向的边缘;原始图像和每个mask进行卷积并且保存起来,对于每个点都标识这个点上的最大值以及生成的边缘的方向:
:在高斯滤波过程中,边缘可能别被放大,因为在真实的图片中,梯度值最大有可能比较多,所以需要对边缘进行过滤,使边缘的宽度尽可能为一个像素点;如果一个像素点属于边缘,那么这个像素点在梯度方向上梯度值最大;否则不是边缘,将像素值设置为0;
:使用一个阈值检测边缘不太合理,使用上下阈值来检测边缘;我们选择valueMax作为高阈值,valueMin作为低阈值;任何梯度值大于高阈值(valueMax)的一定为边缘;任何小于低阈值(valueMin)的一定不是边缘;而对高阈值和低阈值之间的值进行检查,如果边缘相连,则视为边缘;否则不是边缘。
3.Canny函数实现
(5)python中的Canny函数 Canny(InputArray image, double threshold1,double threshold2,OutputArray edges=None, int apertureSize=None,bool L2gradient=None) 参数解释: Image:输入图像(源图像),单通道为8bit; Threshold1:第一个滞后性阈值; Threshold2:第二个滞后性阈值; Edges:输出边缘图,需要和一样的尺寸和数据类型; apertureSize:应用Sobel算子的孔径大小,默认值为3; L2gradient:计算图像梯度幅度值的情况,默认值为False;如果为 True,则使用更精确的 L2 范数进行计算 边缘检测算子:https://blog.csdn.net/wsp_1138886114/article/details/813688904.实例代码测试 (1)图片测试代码
import os
import cv2
import numpy as np
def handl_Canny(pic_path='images/lenna.jpg'):
#读取图像
img=cv2.imread(pic_path)
#缩放图像的大小
img=cv2.resize(src=img,dsize=(512,512))
#对图像进行边缘检测,低阈值=50 高阈值=200
img_canny=cv2.Canny(img,threshold1=50,threshold2=200)
#显示检测之后的图像
cv2.imshow('image',img_canny)
#显示原图像
cv2.imshow('src',img)
cv2.waitKey(0)
#销毁所有的窗口
cv2.destroyAllWindows()
if __name__ == '__main__':
print('PyCharm')
handl_Canny()
(1)调节阈值大小
threshold1=80,threshold2=200
threshold1=130,threshold2=200
threshold1=50,threshold2=220
threshold1=30,threshold2=100
threshold1=30,threshold2=80
总结:可以发现随着threshold1和threshold2的差距变大,检测出的边缘越来越少。因为他们之间的阈值间距越大,那么出现在阈值之间的梯度值就越多,出现不连续的边缘也就越多,导致很多都被过滤掉,所以最后检测出的边缘较少;但是比如threshold1=30,threshold2=100之间相差70,而threshold1=100,threshold2=170之间也是相差70,但是前面一种检测出的边缘又比后面的多,因为梯度值大多数集中在了100以下,所以前面一种检测出的边缘更多。
如果为 True,则使用更精确的 L2 范数进行计算
上比于上面,threshold1=30,threshold2=80,检测出的边缘越来越少了;
Canny(img,threshold1=50,threshold2=200,apertureSize=5)
和上面的threshold1=50,threshold2=200,比较,细节要多了很多。
https://blog.csdn.net/wsp_1138886114/article/details/81368890
import os
import cv2
import numpy as np
def detect_Canny():
cap=cv2.VideoCapture(0)
while cap.isOpened():
OK,frame=cap.read()
# 缩放图像的大小
img = cv2.resize(src=frame, dsize=(512, 512))
# 对图像进行边缘检测,低阈值=50 高阈值=200
img_canny = cv2.Canny(img, threshold1=30, threshold2=100)
# 显示检测之后的图像
cv2.imshow('image', img_canny)
if cv2.waitKey(1)&0xFF==27:
break
cap.release()
cv2.destroyAllWindows()
#销毁所有的窗口
cv2.destroyAllWindows()
if __name__ == '__main__':
print('PyCharm')
detect_Canny()
5.Canny的实际应用
如视觉显著性检测,目标检测,跟踪和运动分析,结构从运动,3D重建,自动驾驶,图像到文本分析等等



