• 图像处理与计算机视觉--第五章-图像分割-Canny算子


    1.边缘检测算子分类

    (1)一阶导数的边缘检测算子:
      通过模板作为核与图像的每个像素点做卷积和运算,然后选取合适的阈值来提取图像的边缘。常见的有Roberts算子、Sobel算子和Prewitt算子。
    (2)二阶导数的边缘算子:
      依据于二阶导数过零点,常见的有Laplacian 算子,此类算子对噪声敏感。
    (3)Canny算子:
      前面两类均是通过微分算子来检测图像边缘,还有一种就是Canny算子,其是在满足一定约束条件下推导出来的边缘检测最优化算子。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.Canny算子核心理论

    2.1.Canny算子简单介绍

    Canny算子是一种非常常用的边缘检测算子,其效果图如下所示:
    在这里插入图片描述

    2.2.Canny算子边缘检测指标

    Canny算子是基于边缘检测来实现的,那么边缘检测的指标如下所示:
    (1)好的信噪比,即将非边缘点判定为边缘点的概率要低。
    (2)高定位,检测出的边缘要在实际边缘中心。
    (3)对单一边缘仅有唯一响应,即虚假边缘要能得到最大抑制。

    2.3.Canny算子基本原理

    1.2个条件:一能有效抑制噪声,二能精确定位边缘位置
    2.平滑后求导,用高斯滤波器进行平滑
    3.用一阶偏导有限差分计算梯度幅值与方向
    3.对梯度幅值进行非极大值抑制
    4.用双闯值检测与连接边缘
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.Canny算子处理流程

    第三部分的内容引用自:https://blog.csdn.net/zaishuiyifangxym/article/details/90142702
    我的工作就是通过其的blog来进行学习,这位博主的cv的专栏写的非常好。
    如果大家这这篇blog中有什么不明白的可以去他的专栏里面看看,内容非常全面,应该能够有比较好的解答。

    3.1.高斯滤波去噪声化

    根据上述算法的第一个原理,我们需要对于图片影响进行去噪声化处理。
    边缘检测容易受到噪声的影像。因此,在进行边缘检测前,通常需要进行去噪。通常,使用高斯滤波来去除噪声,高斯滤波去噪是比较常用的去噪函数合,其5x5的模板公式对应如下:
    1 273 × [ 1 4 7 4 1 4 16 26 16 4 7 26 41 26 7 4 16 26 16 4 1 4 7 4 1 ] \frac{1}{273}\times

    1474141626164726412674162616414741
    2731× 1474141626164726412674162616414741

    在Opencv库当中,高斯滤波的函数如下所示:

    img = cv2.GaussianBlur(src, ksize, sigmaX)
    其中,参数:src 表示原始图像;ksize 表示核大小,而且ksize只能是奇数;sigmaX 表示X方向方差。
    
    • 1
    • 2

    3.2.图像梯度搜寻

    在这一部分的内容当中,我们需要去计算和找寻梯度幅值和方向,寻找图像的梯度。我们需要先将卷积模板分别作用x和y方向,再计算梯度幅值和方向,其公式如下所示:
    卷积化 : d x = [ − 1 0 1 − 2 0 2 − 1 0 1 ] d y = [ − 1 − 2 − 1 0 0 0 1 2 1 ] 幅度 : S = d x 2 + d y 2 方向 : θ = arctan ⁡ ( d y d x )

    :dx:S:θ=121000121dy=101202101=d2x+d2y=arctan(dydx)
    卷积化:dx幅度:S方向:θ= 121000121 dy= 101202101 =dx2+dy2 =arctan(dxdy)
    计算之后得到的幅度和方向如图所示:
                  在这里插入图片描述

    3.3.非极大值抑制处理

      对于每个像素点,它进行如下操作:应用非最大抑制技术来过滤掉非边缘像素,将模糊的边界变得清晰。该过程保留了每个像素点上梯度强度的极大值,过滤掉其他的值。

    Step1:将其梯度方向近似为以下值中的一个,包括04590135180225270315,即表示上下左右和45度方向。
    Step2:比较该像素点和其梯度正负方向的像素点的梯度强度,如果该像素点梯度强度最大则保留,否则抑制(删除,即置为0)。
    
    • 1
    • 2

    Step1和Step2的处理方式如图所示:
    在这里插入图片描述

    3.4.双阈值边界处理

      双阈值边界处理的原理也比较简单,我们对非极大值抑制图像作用两个阈值 T l o w T_{low} Tlow T h i g h T_{high} Thigh。 把梯度值小于 T l o w T_{low} Tlow的像素的灰度值设为0,得到图像1。然后把梯度值大于 T h i g h T_{high} Thigh的像素的灰度值设为0,得到图像2。
     由于图像2的阈值值较高,去除大部分噪音,但同时也损失了有用的边缘信息。而图像1的阈值较低,保留了较多的信息,我们可以以图像2为基础,以图像1为补充来连结图像的边缘。
          在这里插入图片描述

    3.5.边界滞后技术跟踪

    边界滞后技术跟踪的方法研究来自:https://blog.csdn.net/qq_44736333/article/details/109152380

     我们假设两类边缘:经过非极大值抑制之后的边缘点中,梯度值超过T1的称为强边缘,梯度值小于T1大于T2的称为弱边缘,梯度小于T2的不是边缘。
     可以肯定的是,强边缘必然是边缘点,因此必须将T1设置的足够高,以要求像素点的梯度值足够大(变化足够剧烈),而弱边缘可能是边缘,也可能是噪声,如何判断呢?
     当弱边缘的周围8邻域有强边缘点存在时,就将该弱边缘点变成强边缘点,以此来实现对强边缘的补充。
     实际中人们发现T1:T2=2:1的比例效果比较好,其中T1可以人为指定,也可以设计算法来自适应的指定,比如定义梯度直方图的前30%的分界线为T1,我实现的是人为指定阈值。
    在这里插入图片描述
     在上图中,白色方块代表存在边缘(包括强弱边缘),遍历弱边缘中的每个像素,如果像素的八邻域存在强边缘对应的像素,则将这个弱边缘像素归为真正的边缘(从视觉上来理解,就是存在一条不确定的边缘,如果这条不确定的边缘旁存在真正的边缘,则将这条边归为真边,非则就将其删除)

    3.6.Canny算子边缘检测的特点

    1.检出准则: 该准则要求不应丢失重要的边缘,而且不应输出噪声性的多余边缘。
    2.定位准则: 该准则要求检测到的边缘位置与实际边缘位置之间的距离为最小。
    3.单一响应准则: 该准则在一定程度上多涵盖为检出准则,它要求尽可能减少对于同一边缘出现多个响应的情况。
    
    • 1
    • 2
    • 3

    4.Canny算子算法代码

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    # 支持中文
    plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
    plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
    
    def All_Canny(img):
        grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#图像灰度化处理
        gaussian = cv2.GaussianBlur(grayImage, (5, 5), 0)# 高斯滤波降噪
        Canny = cv2.Canny(gaussian, 50, 150)# Canny算子
        return grayImage, gaussian,Canny
    
    # 读取图像
    img = cv2.imread('lena.jpg')#imread出来的是BRG图像
    lenna_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)#转化为RGB图像
    # 显示图形
    Figure=All_Canny(img)#获取Canny检测之后的图片
    
    #图像可视化处理
    titles = [u'原始图像', u'灰度处理图',u'高斯去噪处理图', u'Canny算子c处理图']
    images = [lenna_img ,Figure[0],Figure[1], Figure[2]]
    #subplot绘制
    #第一张图
    plt.subplot(2, 2, 1)
    plt.imshow(images[0], 'gray'),plt.title(titles[0])
    plt.xticks([]),plt.yticks([])
    #第二张图
    plt.subplot(2, 2, 2)
    plt.imshow(images[1], 'gray'),plt.title(titles[1])
    plt.xticks([]),plt.yticks([])
    #第三张图
    plt.subplot(2, 2, 3)
    plt.imshow(images[2], 'gray'),plt.title(titles[2])
    plt.xticks([]),plt.yticks([])
    #第四张图
    plt.subplot(2, 2, 4)
    plt.imshow(images[3], 'gray'),plt.title(titles[3])
    plt.xticks([]),plt.yticks([])
    
    plt.savefig(r"D:\HuaweiMoveData\Users\27182\Desktop\py\Canny.png",dpi=1000)
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    5.Canny算子效果展示

    在这里插入图片描述

    6.参考文章及致谢

    本章内容的完成离不开以下大佬文章的启发和帮助,在这里列出名单,如果对于内容还有不懂的,可以移步对应的文章进行进一步的理解分析。
    1.Canny边缘检测算子流程:https://blog.csdn.net/zaishuiyifangxym/article/details/90142702
    2.边界滞后技术跟踪算法:https://blog.csdn.net/qq_44736333/article/details/109152380
    我的工作就是根据两位大佬的blog来进行学习,这两位博主的cv的专栏写的非常好。
    如果大家这这篇blog中有什么不明白的可以去他们俩个的专栏里面看看,内容非常全面,应该能够有比较好的解答。
    在文章的最后再次表达由衷的感谢!!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    【优化算法】新型多目标热交换MOTEO优化算法(Matlab代码实现)
    低代码不是银弹,为什么很多程序员讨厌低代码?
    互联网轻量级框架整合之MyBatis动态SQL
    【软件设计师 - 一周通关】1.考试介绍
    Springboot初步开发网站(不接数据库,简单增删改查实现)
    企业办理CMMI需要做哪些工作?办理流程是什么
    开发npm第三方库的实战经验
    Python中如何定义类、基类、函数和变量?
    测试右移:线上质量监控 ELK 实战
    21天经典算法之折半查找
  • 原文地址:https://blog.csdn.net/m0_71819746/article/details/133516091