zoukankan      html  css  js  c++  java
  • Canny边缘检测

    1.Canny边缘检测基本原理

         (1)图象边缘检测必须满足两个条件:一能有效地抑制噪声;二必须尽量精确确定边缘的位置。
         (2)根据对信噪比与定位乘积进行测度,得到最优化逼近算子。这就是Canny边缘检测算子。
         (3)类似与Marr(LoG)边缘检测方法,也属于先平滑后求导数的方法。
    2.Canny边缘检测算法
         step1:用高斯滤波器平滑图象;
         step2:用一阶偏导的有限差分来计算梯度的幅值和方向;
         step3:对梯度幅值进行非极大值抑制;
         step4:用双阈值算法检测和连接边缘。
    下面分步来进行讲解:
     
       step1:高斯平滑滤波器(Gaussian Smoothing Filter)
     
        高斯平滑滤波器被使用去模糊图像,和均值滤波器差不多,但是和均值滤波器不一样的地方就是核不同。均值滤波器的核每一个值都是相等,而高斯平滑滤波器的核内的数却是呈现高斯分布的。

    对于二维高斯分布:

     

    它的分布图如下:

            

    作为高斯平滑滤波器的核就应该呈现出上图的布局,例如:

            

    上图分布凸显出了高斯该有的特点,因此,一般而言,高斯平滑滤波器要优于均值滤波器。

    Input Image

            

    Output Image:

    经过一个均值为0,方差为1的高斯核(5*5)进行处理得到下图:

            

    经过一个均值为0,方差为2的高斯核(9*9)处理得到下图:

             

    再经过一个均值为0,方差为4的高斯核(15*15)处理得到下图:

            

        step2:用一阶偏导的有限差分来计算梯度的幅值和方向

     

      

        step3:对梯度幅值进行非极大值抑制(Non-maximum suppression, NMS)

            图像梯度幅值矩阵中的元素值越大,说明图像中该点的梯度值越大,但这不不能说明该点就是边缘(这仅仅是属于图像增强的过程)。在Canny算法中,非极大值抑制是进行边缘检测的重要步骤,通俗意义上是指寻找像素点局部最大值,将非极大值点所对应的灰度值置为0,这样可以剔除掉一大部分非边缘的点。

    图1 非极大值抑制原理

            根据图1 可知,要进行非极大值抑制,就首先要确定像素点C的灰度值在其8值邻域内是否为最大。图1中蓝色的线条方向为C点的梯度方向,这样就可以确定其局部的最大值肯定分布在这条线上,也即出了C点外,梯度方向的交点dTmp1和dTmp2这两个点的值也可能会是局部最大值。因此,判断C点灰度与这两个点灰度大小即可判断C点是否为其邻域内的局部最大灰度点。如果经过判断,C点灰度值小于这两个点中的任一个,那就说明C点不是局部极大值,那么则可以排除C点为边缘。这就是非极大值抑制的工作原理。

            作者认为,在理解的过程中需要注意以下两点:

            1)中非最大抑制是回答这样一个问题:“当前的梯度值在梯度方向上是一个局部最大值吗?” 所以,要把当前位置的梯度值与梯度方向上两侧的梯度值进行比较;

            2)梯度方向垂直于边缘方向。

            但实际上,我们只能得到C点邻域的8个点的值,而dTmp1和dTmp2并不在其中,要得到这两个值就需要对该两个点两端的已知灰度进行线性插值,也即根据图1中的g1和g2对dTmp1进行插值,根据g3和g4对dTmp2进行插值,这要用到其梯度方向,这是上文Canny算法中要求解梯度方向矩阵Thita的原因。

            完成非极大值抑制后,会得到一个二值图像,非边缘的点灰度值均为0,可能为边缘的局部灰度极大值点可设置其灰度为128。根据下文的具体测试图像可以看出,这样一个检测结果还是包含了很多由噪声及其他原因造成的假边缘。因此还需要进一步的处理。

        step4:用双阈值算法检测和连接边缘

        

            对非极大值抑制图像作用两个阈值th1和th2,两者关系th1=0.4th2。我们把梯度值小于th1的像素的灰度值设为0,得到图像1。然后把梯度值小于th2的像素的灰度值设为0,得到图像2。由于图像2的阈值较高,去除大部分噪音,但同时也损失了有用的边缘信息。而图像1的阈值较低,保留了较多的信息,我们可以以图像2为基础,以图像1为补充来连结图像的边缘。

      链接边缘的具体步骤如下:

      对图像2进行扫描,当遇到一个非零灰度的像素p(x,y)时,跟踪以p(x,y)为开始点的轮廓线,直到轮廓线的终点q(x,y)。

      考察图像1中与图像2中q(x,y)点位置对应的点s(x,y)的8邻近区域。如果在s(x,y)点的8邻近区域中有非零像素s(x,y)存在,则将其包括到图像2中,作为r(x,y)点。从r(x,y)开始,重复第一步,直到我们在图像1和图像2中都无法继续为止。

      当完成对包含p(x,y)的轮廓线的连结之后,将这条轮廓线标记为已经访问。回到第一步,寻找下一条轮廓线。重复第一步、第二步、第三步,直到图像2中找不到新轮廓线为止。

      至此,完成canny算子的边缘检测。

       参考文献:http://www.cnblogs.com/cfantaisie/archive/2011/06/05/2073168.html

            http://www.xuebuyuan.com/1541968.html


  • 相关阅读:
    AVUE 根据 某个字段 倒序查询
    Java hutool工具包的使用
    AVUE 添加搜索项
    SpringBlade 添加 回收站功能
    接口 form-data 将对象转换为复杂url参数
    AVUE 隐藏 新增按钮
    AVUE 查看crud列的属性配置
    AVUE dialog对话框 去掉 点击屏幕空白区 就关闭弹框
    接口 C#/Java 请求数据 raw 的方式传输复杂对象
    接口 PostMan 常用
  • 原文地址:https://www.cnblogs.com/centor/p/5937788.html
Copyright © 2011-2022 走看看