Canny边缘检测
1.Canny边缘检测基本原理
下面分步来进行讲解:
对于二维高斯分布:

它的分布图如下:
作为高斯平滑滤波器的核就应该呈现出上图的布局,例如:
上图分布凸显出了高斯该有的特点,因此,一般而言,高斯平滑滤波器要优于均值滤波器。
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 可知,要进行非极大值抑制,就首先要确定像素点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
Canny边缘检测的更多相关文章
- OpenCV图像Canny边缘检测
Canny边缘检测 图像的边缘检测的原理是检测出图像中所有灰度值变化较大的点,而且这些点连接起来就构成了若干线条,这些线条就可以称为图像的边缘函数原型: void cvCanny( ...
- OpenCV: Canny边缘检测算法原理及其VC实现详解(转载)
原文地址:http://blog.csdn.net/likezhaobin/article/details/6892176 原文地址:http://blog.csdn.net/likezhaobin/ ...
- 从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中
//从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中 //作者:sandy //时间:2015-10-10 #inclu ...
- [转载+原创]Emgu CV on C# (六) —— Emgu CV on Canny边缘检测
Canny边缘检测也是一种边缘检测方法,本文介绍了Canny边缘检测的函数及其使用方法,并利用emgucv方法将轮廓检测解算的结果与原文进行比较. 图像的边缘检测的原理是检测出图像中所有灰度值变化较大 ...
- ###Canny边缘检测算子
开源中国. #@date: 2014-06-20 #@author: gerui #@email: forgerui@gmail.com 一.一阶微分边缘算子 1. 一阶微分边缘检测算子也称梯度边缘算 ...
- openCV(四)---Canny边缘检测
图像的边缘检测的原理是检测出图像中所有灰度值变化较大的点,而且这些点连接起来就构成了若干线条,这些线条就可以称为图像的边缘. 直接上代码,函数简介都在代码注释中 //canny边缘检测 -(void) ...
- Canny边缘检测算法的实现
图像边缘信息主要集中在高频段,通常说图像锐化或检测边缘,实质就是高频滤波.我们知道微分运算是求信号的变化率,具有加强高频分量的作用.在空域运算中来说,对图像的锐化就是计算微分.由于数字图像的离散信号, ...
- 一些关于Canny边缘检测算法的改进
传统的Canny边缘检测算法是一种有效而又相对简单的算法,可以得到很好的结果(可以参考上一篇Canny边缘检测算法的实现).但是Canny算法本身也有一些缺陷,可以有改进的地方. 1. Canny边缘 ...
- [学习OpenCV攻略][008][Canny边缘检测]
cvGetSize(输入图片) 得到输入图片的大小 cvCanny(输入图片,输出图片,lowThresh,highThresh,aperture) 把输入图片按设定光圈值进行Canny边缘检测,然后 ...
随机推荐
- 创建两个对象的两种方法,一中\new,另外一种不new
方法一: String s1=new String("hello"); String s2=new String("hello"); 这里是new了 ...
- mysql排序时索引的注意事项
参考 'mysql高性能'
- 使用MyBatis对表执行CRUD操作
一.使用MyBatis对表执行CRUD操作——基于XML的实现 1.定义sql映射xml文件 userMapper.xml文件的内容如下: <?xml version="1.0&quo ...
- javascript立即执行函数
javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花;当然,能理解各型各色的写法也是对javascript语言特性更进一步的深入理解. ( ...
- Javascript,颜色渐变效果的处理
在搭建博主博客的时候,寻思着做一些效果,看到菜单,就想是不是可以做一下颜色的渐变,增加一点动态的感觉.有个jquery的插件,效果相当不错,不过博主还是打算自立更生写一下,看看能不能实现. 下面就是博 ...
- Flink – window operator
参考, http://wuchong.me/blog/2016/05/25/flink-internals-window-mechanism/ http://wuchong.me/blog/201 ...
- ASP.NET Web API 2基于令牌的身份验证
基于令牌的认证 我们知道WEB网站的身份验证一般通过session或者cookie完成的,登录成功后客户端发送的任何请求都带上cookie,服务端根据客户端发送来的cookie来识别用户. WEB A ...
- 用Arduino剖析PWM脉宽调制
PWM(Pulse Width Modulation)简介 PWM,也就是脉冲宽度调制,用于将一段信号编码为脉冲信号,也就是方波信号.多用于在数字电路中驱动负载随时间变化的电子元件,如LED,电机等. ...
- 关于复选框input[type=checkbox]
关于复选框input[type=checkbox],其实在前面的文章中说过一次,当时主要关注点在设置复选框的状态,利用prop实现,今天继续关注一下复选框. 自己在项目中,遇到一个全选/全不选的需求, ...
- vuejsLearn--- -- 怎么查看、修改、追加数据---->data对象
实例观察的数据对象.可以用一个新的对象替换.实例代理了它的数据对象的属 我们现在对data2添加几项 使用数组push()追加 但是直接这样不能进行数组操作 var data2 = { city: ' ...