canny算法原理

图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般可以看作是一个阶跃,既从一个灰度值在很小的缓冲区域内急剧变化到另一个灰度相差较大的灰度值。图象的边缘部分集中了图象的大部分信息,图象边缘的确定与提取对于整个图象场景的识别与理解是非常重要的,同时也是图象分割所依赖的重要特征,边缘检测主要是图象的灰度变化的度量、检测和定位,自从1959提出边缘检测以来,经过五十多年的发展,已有许多中不同的边缘检测方法。根据作者的理解和实践,本文对边缘检测的原理进行了描述,在此基础上着重对Canny检测算法的实现进行详述。

        本文所述内容均由编程验证而来,在实现过程中,有任何错误或者不足之处大家共同讨论(本文不讲述枯燥的理论证明和数学推导,仅仅从算法的实现以及改进上进行原理性和工程化的描述)。

1、边缘检测原理及步骤

        在之前的博文中,作者从一维函数的跃变检测开始,循序渐进的对二维图像边缘检测的基本原理进行了通俗化的描述。结论是:实现图像的边缘检测,就是要用离散化梯度逼近函数根据二维灰度矩阵梯度向量来寻找图像灰度矩阵的灰度跃变位置,然后在图像中将这些位置的点连起来就构成了所谓的图像边缘(图像边缘在这里是一个统称,包括了二维图像上的边缘、角点、纹理等基元图)。

        在实际情况中理想的灰度阶跃及其线条边缘图像是很少见到的,同时大多数的传感器件具有低频滤波特性,这样会使得阶跃边缘变为斜坡性边缘,看起来其中的强度变化不是瞬间的,而是跨越了一定的距离。这就使得在边缘检测中首先要进行的工作是滤波。

        1)滤波:边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此必须采用滤波器来改善与噪声有关的边缘检测器的性能。常见的滤波方法主要有高斯滤波,即采用离散化的高斯函数产生一组归一化的高斯核(具体见“高斯滤波原理及其编程离散化实现方法”一文),然后基于高斯核函数对图像灰度矩阵的每一点进行加权求和(具体程序实现见下文)。

        2)增强:增强边缘的基础是确定图像各点邻域强度的变化值。增强算法可以将图像灰度点邻域强度值有显著变化的点凸显出来。在具体编程实现时,可通过计算梯度幅值来确定。

        3)检测:经过增强的图像,往往邻域中有很多点的梯度值比较大,而在特定的应用中,这些点并不是我们要找的边缘点,所以应该采用某种方法来对这些点进行取舍。实际工程中,常用的方法是通过阈值化方法来检测。

2、Canny边缘检测算法原理

        JohnCanny于1986年提出Canny算子,它与Marr(LoG)边缘检测方法类似,也属于是先平滑后求导数的方法。本节对根据上述的边缘检测过程对Canny检测算法的原理进行介绍。

2.1 对原始图像进行灰度化

        Canny算法通常处理的图像为灰度图,因此如果摄像机获取的是彩色图像,那首先就得进行灰度化。对一幅彩色图进行灰度化,就是根据图像各个通道的采样值进行加权平均。以RGB格式的彩图为例,通常灰度化采用的方法主要有:

        方法1:Gray=(R+G+B)/3;

        方法2:Gray=0.299R+0.587G+0.114B;(这种参数考虑到了人眼的生理特点)

        注意1:至于其他格式的彩色图像,可以根据相应的转换关系转为RGB然后再进行灰度化;

        注意2:在编程时要注意图像格式中RGB的顺序通常为BGR

2.2 对图像进行高斯滤波

        图像高斯滤波的实现可以用两个一维高斯核分别两次加权实现,也可以通过一个二维高斯核一次卷积实现。

        1)高斯核实现

       上式为离散化的一维高斯函数,确定参数就可以得到一维核向量。


        上式为离散化的二维高斯函数,确定参数就可以得到二维核向量。

        注意1:关于参数Sigma的取值详见上篇博文。

        注意2:在求的高斯核后,要对整个核进行归一化处理。

2)图像高斯滤波

        对图像进行高斯滤波,听起来很玄乎,其实就是根据待滤波的像素点及其邻域点的灰度值按照一定的参数规则进行加权平均。这样可以有效滤去理想图像中叠加的高频噪声。

        通常滤波和边缘检测是矛盾的概念,抑制了噪声会使得图像边缘模糊,这回增加边缘定位的不确定性;而如果要提高边缘检测的灵敏度,同时对噪声也提高了灵敏度。实际工程经验表明,高斯函数确定的核可以在抗噪声干扰和边缘检测精确定位之间提供较好的折衷方案。这就是所谓的高斯图像滤波,具体实现代码见下文。

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

        关于图像灰度值得梯度可使用一阶有限差分来进行近似,这样就可以得图像在x和y方向上偏导数的两个矩阵。常用的梯度算子有如下几种:

        1)Roberts算子


        上式为其x和y方向偏导数计算模板,可用数学公式表达其每个点的梯度幅值为:

        2)Sobel算子

canny算法原理_第1张图片

        上式三个矩阵分别为该算子的x向卷积模板、y向卷积模板以及待处理点的邻域点标记矩阵,据此可用数学公式表达其每个点的梯度幅值为:

canny算法原理_第2张图片

        3)Prewitt算子

        和Sobel算子原理一样,在此仅给出其卷积模板。

canny算法原理_第3张图片

        4)Canny算法所采用的方法

        在本文实现的Canny算法中所采用的卷积算子比较简单,表达如下:


        其x向、y向的一阶偏导数矩阵,梯度幅值以及梯度方向的数学表达式为:

canny算法原理_第4张图片

        求出这几个矩阵后,就可以进行下一步的检测过程。

2.4 对梯度幅值进行非极大值抑制

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

canny算法原理_第5张图片

图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。根据下文的具体测试图像可以看出,这样一个检测结果还是包含了很多由噪声及其他原因造成的假边缘。因此还需要进一步的处理。

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

        Canny算法中减少假边缘数量的方法是采用双阈值法。选择两个阈值(关于阈值的选取方法在扩展中进行讨论),根据高阈值得到一个边缘图像,这样一个图像含有很少的假边缘,但是由于阈值较高,产生的图像边缘可能不闭合,未解决这样一个问题采用了另外一个低阈值。

        在高阈值图像中把边缘链接成轮廓,当到达轮廓的端点时,该算法会在断点的8邻域点中寻找满足低阈值的点,再根据此点收集新的边缘,直到整个图像边缘闭合。

        以上即为整个Canny边缘检测算法的原理分析,接下来我们进行VC下的算法实现和效果分析。


1、图像滤波

         在三维计算机视觉领域,通常对于二维图像的特征抽取是很关键的第一步,这主要包括抽取二维图像上的边缘、角点、纹理等。通常从这些被称为基元图的组成部分中,我们可以提取图像的以下特征:

        1)不同物体边缘成像所带来的灰度跃变;

        2)物体不同材料或者不同颜色组成部分之间的分界线会产生灰度跃变;

        3)物体轮廓线与背景具有不同的反射特性,也会形成灰度值不连续;

        4)物体受到光照会形成阴影,这也会形成层灰度的跃变。

       从上面分析可以看出,如果能够较好的从二维图像中提取出这些信息,那么对于三维重建,物体定位,空间监控等后期目标能够有很好的支撑作用。而这些含有图像轮廓以及空间位置信息的点、线、面等特征,在图像上都体现为灰度值的不连续或者剧烈变化。也就是说,如果我们能够根据图像灰度矩阵找到灰度不连续的点位置,那么也就是实现了特征抽取。

        不失一般性,从最简单的一维信号回忆,如果我们想从一维信号中找到其不连续的点,那么根据高等数学内容,可以对信号求导,其一阶导数局部最大值即为信号剧烈变化的点。

        在二维函数中,梯度向量代表着函数的最大变化率方向,因此对于二维信号,可以采用其梯度向量的模来选取灰度值不连续点。这样在理想情况下,我们就可以用离散化的梯度逼近函数来检测图像灰度矩阵的灰度跃变位置,从而实现特征抽取。

        现实中,有摄像机获取的图像,往往都存在噪声,而且信号并不存在理想的阶跃畸变,这样如果依然直接采用拉普拉斯算子进行灰度跃变检测,那样会产生很多的虚假特征点。因此,往往在图像处理之前,需要对灰度图进行滤波处理。

2、高斯滤波原理

           高斯滤波是最常用的一种图像滤波方法,本文就要对这种滤波的思路以及具体的编程实现原理进行挖掘整理。

2.1噪声的特性总结

       通常信息处理系统的目标是从测量到的带有噪声的信号中提取出真实的有用的信息,而往往真实有用信息是不可知的,因此只能通过滤波的方法进行信息估计。

       在我们进行数学仿真或者误差评估是,往往认为传感器所引入的噪声服从正态分布(高斯白噪声),这样我们在进行滤波的时候就可以有针对性的来进行滤波器设计。

2.2滤波通俗理解

       滤波就是根据观测某一随机过程的结果,对另一与之有关的随机过程进行估计的概率理论与方法。更通俗点讲,滤波就是建立的一个数学模型,通过这个模型来将图像数据进行能量转化,而能量低的就排除掉,噪声就是属于低能量部分。

       通常从传感器所获得的数据都是离散的,常用的图像滤波方法都是根据像素点附近邻域像素的灰度值进行相应的加权平均所得(经过实际检验,通过这样,可以有效的消除近似白噪声的噪声信号,对于图像滤波来说,这会使得图像边缘相比滤波前模糊一点),不同的滤波方法这个权值大小以及所加权的数据范围不同。

2.3 高斯滤波

       引入高斯滤波函数为:

                  

       该函数各向同性,其曲线是草帽状的对称图,该曲线对整个覆盖面积求积分为1。高斯滤波的思路就是:对高斯函数进行离散化,以离散点上的高斯函数值为权值,对我们采集到的灰度矩阵的每个像素点做一定范围邻域内的加权平均,即可有效消除高斯噪声。

3、高斯滤波离散化算法实现


       可以发现很多教材以及网上的资料都描述高斯滤波的原理是采用高斯算子对图像进行卷积运算。其实在各个算法库如Matlab、OpenCV等,在实现的时候,就是采用一个矩阵模板进行加权运算,拿图像的八连通区域来说,中间点的像素值就等于八连通区的像素值的均值,这样达到平滑的效果,该模板我们常成为高斯核。

       根据上述分析可知,高斯核是整个求解的关键。很显然,它是通过二维高斯函数计算得来的。这里给出离散高斯核矩阵的计算公式。

       离散的高斯卷积核H: (2k+1)×(2k+1)维,其元素计算方法为:


       其中Sigma为方差,k确定核矩阵的维数,关于这两个取值,在下文进行分析。

4、与matlab函数运行结果对比

      这里对高斯卷积核的矩阵算法进行验证。

      1)在matlab中用以下代码可以产生一个3×3的核。

                                               filter=fspecial('gaussian',3,1);

      所产生的核矩阵为:

                                   filter =

                                              0.0751    0.1238   0.0751

                                              0.1238    0.2042   0.1238

                                              0.0751   0.1238    0.0751

      2)同样对于上述的公式,我们取k=1,Sigma=1,即可得到3×3的高斯卷积核如下:

      canny算法原理_第6张图片

      上文说到,我们进行加权滤波,权系数之和必须为1,上面所求出的高斯滤波核函数同样的必须进行归一化:

  canny算法原理_第7张图片

1 图像滤波的基本概念

图像常常被强度随机信号(也称为噪声)所污染.一些常见的噪声有椒盐(Salt
& Pepper
)噪声、脉冲噪声、高斯噪声等.椒盐噪声含有随机出现的黑白强度值.而脉冲噪声则只含有随机的白强度值(正脉冲噪声)或黑强度值(负脉冲噪声).与前两者不同,高斯噪声含有强度服从高斯或正态分布的噪声.研究滤波就是为了消除噪声干扰。

图像滤波总体上讲包括空域滤波和频域滤波。频率滤波需要先进行傅立叶变换至频域处理然后再反变换回空间域还原图像,空域滤波是直接对图像的数据做空间变换达到滤波的目的。它是一种邻域运算,即输出图像中任何像素的值都是通过采用一定的算法,根据输入图像中对用像素周围一定邻域内像素的值得来的。如果输出像素是输入像素邻域像素的线性组合则称为线性滤波(例如最常见的均值滤波和高斯滤波),否则为非线性滤波(中值滤波、边缘保持滤波等)。

线性平滑滤波器去除高斯噪声的效果很好,且在大多数情况下,对其它类型的噪声也有很好的效果。线性滤波器使用连续窗函数内像素加权和来实现滤波。特别典型的是,同一模式的权重因子可以作用在每一个窗口内,也就意味着线性滤波器是空间不变的,这样就可以使用卷积模板来实现滤波。如果图像的不同部分使用不同的滤波权重因子,且仍然可以用滤波器完成加权运算,那么线性滤波器就是空间可变的。任何不是像素加权运算的滤波器都属于非线性滤波器.非线性滤波器也可以是空间不变的,也就是说,在图像的任何位置上可以进行相同的运算而不考虑图像位置或空间的变化。

2 图像滤波的计算过程分析

滤波通常是用卷积或者相关来描述,而线性滤波一般是通过卷积来描述的。他们非常类似,但是还是会有不同。下面我们来根据相关和卷积计算过程来体会一下他们的具体区别:

卷积的计算步骤:

(1)       卷积核绕自己的核心元素顺时针旋转180

(2)       移动卷积核的中心元素,使它位于输入图像待处理像素的正上方

(3)       在旋转后的卷积核中,将输入图像的像素值作为权重相乘

(4)       第三步各结果的和做为该输入像素对应的输出像素

相关的计算步骤:

1移动相关核的中心元素,使它位于输入图像待处理像素的正上方

2将输入图像的像素值作为权重,乘以相关核

3将上面各步得到的结果相加做为输出

可以看出他们的主要区别在于计算卷积的时候,卷积核要先做旋转。而计算相关过程中不需要旋转相关核。


你可能感兴趣的:(canny算法原理)