Canny算子是JohnCanny在1986年提出的,那年老大爷才28岁,该文章发表在PAMI顶级期刊上的(1986.A computational approach to edge detection. IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 8, 1986, pp. 679-698)。老大爷目前在加州伯克利做machine learning,80-90年代视觉都是图像处理,现在做视觉都是机器学习的天下,大爷的主页(~jfc/)。
Canny算子与Marr(LoG)边缘检测方法类似(Marr大爷号称计算机视觉之父),也属于是先平滑后求导数的方法。JohnCanny研究了最优边缘检测方法所需的特性,给出了评价边缘检测性能优劣的三个指标:
1 好的信噪比,即将非边缘点判定为边缘点的概率要低,将边缘点判为非边缘点的概率要低;
2高的定位性能,即检测出的边缘点要尽可能在实际边缘的中心;
3对单一边缘仅有唯一响应,即单个边缘产生多个响应的概率要低,并且虚假响应边缘应该得到最大抑制。
用一句话说,就是希望在提高对景物边缘的敏感性的同时,可以抑制噪声的方法才是好的边缘提取方法。
Canny算子求边缘点具体算法步骤如下:
1.用高斯滤波器平滑图像.
2.用一阶偏导有限差分计算梯度幅值和方向
3.对梯度幅值进行非极大值抑制
4.用双阈值算法检测和连接边缘.
具体的步骤是能容易理解,现在就是用C语言怎么实现了,在参考了网上诸多教程的基础下,写了个代码给大家参考,肯定有不少问题,希望能得到大家的指点。
首先用白话叙述下Canny算子的原理:看作者写的paper题目就是边缘检测,何为边缘?图象局部区域亮度变化显著的部分,对于灰度图像来说,也就是灰度值有一个明显变化,既从一个灰度值在很小的缓冲区域内急剧变化到另一个灰度相差较大的灰度值。依据我仅有的数学知识,怎么表征这种灰度值的变化呢?导数就是表征变化率的,但是数字图像都是离散的,也就是导数肯定会用差分来代替。也就是具体算法中的步骤2。但是在真实的图像中,一般会有噪声,噪声会影响梯度(换不严格说法 偏导数)的计算,所以步骤1上来先滤波。理论上将图像梯度幅值的元素值越大,说明图像中该点的梯度值越大,但这不能说明该点就是边缘。在Canny算法中,非极大值抑制(步骤3)是进行边缘检测的重要步骤,通俗意义上是指寻找像素点局部最大值,沿着梯度方向,比较它前面和后面的梯度值进行了。步骤4,是一个典型算法,有时候我们并不像一刀切,也就是超过阈值的都是边缘点,而是设为两个阈值,希望在高阈值和低阈值之间的点也可能是边缘点,而且这些点最好在高阈值的附近,也就是说这些中间阈值的点是高阈值边缘点的一种延伸。canny边缘检测原理所以步骤4用了双阈值来检测和连接边缘。
基本原理简单说完,上代码,代码按照下面6步骤叙述。
第一步:灰度化
第二步:高斯滤波
第三步:计算梯度值和方向
第四步:非极大值抑制
第五步:双阈值的选取
第六步:边缘检测
1 把彩像变成灰度图像。该部分主要是为像我这样的小菜鸟准备的。
该部分是按照Canny算法通常处理的图像为灰度图,如果获取的彩像,那首先就得进行灰度化。以RGB格式的彩图为例,通常灰度化采用的公式是:
Gray=0.299R+0.587G+0.114B;
说个我经常出问题的代码:OpenCvGrayImage->imageData[i*OpenCvGrayImage->widthStep+j] 这是opencv iplimage格式通过直接访问内存读取像素值的方式,我一直搞不清楚,i*widthStep还是j*widthStep。canny边缘检测原理
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-34002-1.html
必须反击