栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Opencv中的Canny边缘检测

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Opencv中的Canny边缘检测

文章目录
    • 1.Canny引入
    • 2.Canny算法实现步骤
      • (1)去噪
      • (2)计算梯度和梯度方向
      • (3)过滤非最大值
      • (4)使用阈值检测边缘
    • 3.Canny函数实现
    • 4.实例代码测试
      • (1)图片测试代码
        • (1)调节阈值大小
        • (2)使用L2gradient=True
        • (3)设置apertureSize中的Sobel算子大小
      • (2)实时检测代码
    • 5.Canny的实际应用

1.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进行卷积并且保存起来,对于每个点都标识这个点上的最大值以及生成的边缘的方向:

(3)过滤非最大值

:在高斯滤波过程中,边缘可能别被放大,因为在真实的图片中,梯度值最大有可能比较多,所以需要对边缘进行过滤,使边缘的宽度尽可能为一个像素点;如果一个像素点属于边缘,那么这个像素点在梯度方向上梯度值最大;否则不是边缘,将像素值设置为0;

(4)使用阈值检测边缘

:使用一个阈值检测边缘不太合理,使用上下阈值来检测边缘;我们选择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/81368890
4.实例代码测试 (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以下,所以前面一种检测出的边缘更多。

(2)使用L2gradient=True

如果为 True,则使用更精确的 L2 范数进行计算

上比于上面,threshold1=30,threshold2=80,检测出的边缘越来越少了;

(3)设置apertureSize中的Sobel算子大小

Canny(img,threshold1=50,threshold2=200,apertureSize=5)

和上面的threshold1=50,threshold2=200,比较,细节要多了很多。
https://blog.csdn.net/wsp_1138886114/article/details/81368890

(2)实时检测代码
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重建,自动驾驶,图像到文本分析等等

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/954687.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号