传统的Canny边缘检测算法是一种有效而又相对简单的算法,可以得到很好的结果(可以参考上一篇Canny边缘检测算法的实现)。但是Canny算法本身也有一些缺陷,可以有改进的地方。

1. Canny边缘检测第一步用高斯模糊来去掉噪声,但是同时也会平滑边缘,使得边缘信息减弱,有可能使得在后面的步骤中漏掉一些需要的边缘,特别是弱边缘和孤立的边缘,可能在双阀值和联通计算中被剔除。很自然地可以预见,如果加大高斯模糊的半径,对噪声的平滑力度加大,但也会使得最后得到的边缘图中的边缘明显减少。这里依然用Lena图为例,保持Canny算法中高阀值100,低阀值50不变,高斯半径分别为2,3,5的Canny边缘二值图像如下。可知高斯模糊把很多有用的边缘信息也模糊掉了,因此如何精确的选择高斯半径就相当重要。

     

高斯半径2                                          高斯半径3                                          高斯半径5

2. 在最初的Canny算法中是使用的最小的2x2领域来计算梯度幅值的。这种方法对噪声很敏感,比较容易检测到伪边缘或漏掉真是边缘。在上一篇算法实现中,实际上使用的是3x3的Sobel梯度算子,是一种比较好的选择。

3. 传统Canny算法的双阀值是全局固定的,因此双阀值大小的选取对最终的结果影响很大,也有一些经验,比如选择低阀值是高阀值的0.4或0.5。然而这毕竟是一种经验选择,阀值的确定仍然很难决定一个最优值。而且一个图像的不同局部区域可能需要各不相同的阀值来精确地找到真实边缘,因此全局阀值就不太合适了。

4. 传统算法仍然可能产生一条宽度大于1的边缘,达不到满意的高精度单点响应。也就是需要继续细化边缘。

下面就一些可以改进的地方做一些讨论。

代替高斯模糊

噪声是高频信号,边缘信号也属于高频信号。既然高斯模糊不加区分的对所有的高频信息进行了模糊,效果自然不尽如人意。那么自然就想到了带有保留边缘功能的各种选择性平滑方法,似乎在这里比高斯模糊会更加合适,那我们就来试一试。带有保留边缘功能的平滑方法的基本思想不是让领域范围内的所有像素都参与该种平滑方法的计算,而是设定一个阀值,仅仅让和中心像素灰度的差值小于这个阀值的像素参与计算。这样和中心像素相差过大的像素被认为是带有有效的信息,而不是噪声,不会参与平滑计算,从而保留了这些有用的高频信号,那么边缘信号自然也在保留的范围。具体的算法可以参考这篇文章http://www.cnblogs.com/Imageshop/p/4694540.html,已经讲得很清楚了。无论是均值平滑,中值平滑,表面模糊,都可以参考这种算法来实现选择性模糊。

应用有保留边缘的选择性模糊来代替高斯模糊后,可以发现,模糊领域的半径值基本影响不了Canny检测的结果,最后的结果只跟选择模糊设定的阀值有关。下面以均值模糊为例,Canny检测的高阀值100低阀值50不变,均值模糊阀值30,不同模糊半径的结果。在均值模糊阀值不变的情况下,不同领域半径下,最后的结果差别不大。

     

均值模糊半径2,阀值30                     均值模糊半径5,阀值30                           均值模糊半径15,阀值30

而保持模糊半径5不变的话,使用不同模糊门限阀值,阀值越大,也就是有越多的领域像素参与模糊计算,最后保留的边缘就越少了。

  

均值模糊半径5,阀值40                         均值模糊半径5,阀值50

相对于高斯模糊,在相同半径下,可以看出应用有保留边缘功能的选择性模糊,明显能保留了更多的边缘细节,使得很多相对较弱的边缘得意保留下来了。我另外还实验了选择性的中值模糊,表面模糊,他们和选择性的均值模糊都能达到类似的效果。这里就不一一列举结果了。其中选择性的表面模糊,因为中心像素的权重高,最后Canny检测结果在参数相同的情况下,保留的边缘相对较多一些。总的来说,应用有保留边缘功能的选择性模糊来代替高斯模糊,参数的选择(领域半径和阀值门限)不像高斯模糊半径参数选择那么严格,所以检测结果更稳定一些。但是参数要多了一个。

梯度算子选择

对于算法中梯度的计算,梯度算子可以有多种选择。我试了一下,如果用一阶梯度算子,Robert交叉算子,他们都是2x2的算子,来代替Sobel,保持高斯模糊半径2,高阀值100低阀值50不变,结果如下。要注意的是,由于一阶梯度算子和Robert算子都是2x2的算子,他们算出来的梯度在幅度上都要小于Sobel算子。即使用同样的高低阀值,最后的结果也不具有可比性。因此,参照Sobel算子的幅度,2x2算子的x,y方向梯度都乘以相应地倍数(4倍),最后进行比较。

     

一阶差分Canny二值图                        Robert交叉梯度Canny二值图                   Sobel算子Canny二值图

可以看到,一阶差分最后的结果在边缘的连通性上是最差的,Robert算子要好一些,Sobel算子最好。在这几种选择当中,似乎Sobel算子是最好的选择。另外还可以使用Prewitt算子和5x5Sobel算子。Prewitt算子也是3x3的,仅仅参数不同,在平滑性能上略微不如Sobel算子。一般来说,比如在Lena图上,Canny边缘结果和用Sobel算子的结果差别不大。5x5Sobel算子在平滑性能上要更强一些。

Canny边缘检测算法的一些改进的更多相关文章

  1. 一些关于Canny边缘检测算法的改进

    传统的Canny边缘检测算法是一种有效而又相对简单的算法,可以得到很好的结果(可以参考上一篇Canny边缘检测算法的实现).但是Canny算法本身也有一些缺陷,可以有改进的地方. 1. Canny边缘 ...

  2. OpenCV: Canny边缘检测算法原理及其VC实现详解(转载)

    原文地址:http://blog.csdn.net/likezhaobin/article/details/6892176 原文地址:http://blog.csdn.net/likezhaobin/ ...

  3. Canny边缘检测算法原理及其VC实现详解(一)

    转自:http://blog.csdn.net/likezhaobin/article/details/6892176 图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般可以看作是一个 ...

  4. 【算法随记】Canny边缘检测算法实现和优化分析。

    以前的博文大部分都写的非常详细,有很多分析过程,不过写起来确实很累人,一般一篇好的文章要整理个三四天,但是,时间越来越紧张,后续的一些算法可能就以随记的方式,把实现过程的一些比较容易出错和有价值的细节 ...

  5. 十五 Canny边缘检测算法

    一.Canny算法介绍 Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是: 好的检测- 算法能够尽可能多地标识出图像中的实际边缘. 好的定位- 标识出的边缘要尽可能与实际图像中的实 ...

  6. 【数字图像分析】基于Python实现 Canny Edge Detection(Canny 边缘检测算法)

    Canny 边缘检测算法 Steps: 高斯滤波平滑 计算梯度大小和方向 非极大值抑制 双阈值检测和连接 代码结构: Canny Edge Detection | Gaussian_Smoothing ...

  7. Canny边缘检测算法(基于OpenCV的Java实现)

    目录 Canny边缘检测算法(基于OpenCV的Java实现) 绪论 Canny边缘检测算法的发展历史 Canny边缘检测算法的处理流程 用高斯滤波器平滑图像 彩色RGB图像转换为灰度图像 一维,二维 ...

  8. Canny边缘检测算法原理及其VC实现详解(二)

    转自:http://blog.csdn.net/likezhaobin/article/details/6892629 3.  Canny算法的实现流程 由于本文主要目的在于学习和实现算法,而对于图像 ...

  9. Canny边缘检测算法原理及C语言实现详解

    Canny算子是John Canny在1986年提出的,那年老大爷才28岁,该文章发表在PAMI顶级期刊上的(1986. A computational approach to edge detect ...

随机推荐

  1. dubbo常用配置及注意事项

    1.启动时检查缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true. 关闭所有服务的启动时检查:(没有提供者时报错 ...

  2. ImageDrawer.js图片绘制插件

    ImageDrawer.js图片绘制插件有以下一些可用的配置参数. Duration:整个动画或每个步骤的绘制时间(以秒为单位) Background:在绘图时将颜色放在图片上 Callback:绘画 ...

  3. linux 查看文件显示行号

    1.用vi或vim打开文件显示行号: 显示当前行号:  :nu 显示所有行号:  :set nu 2.设置服务器显示行号 2.1编辑~/.vimrc文件,在该文件中加入 set nu 2.2在UBUN ...

  4. !!!常用CSS代码块

    图片排满一行.左右两端无间隙. <style type="text/css"> .img_abc{float:left;width:30%;margin-left:5% ...

  5. PHP实现JS点击点击定位

    点击class='women' 定位到 class='m=foot'$(".women").on('click',function(){ $("html, body&qu ...

  6. spring boot报Unsupported Media Type Content type '*/*;charset=UTF-8' not supported

    1.请求设置Content-Type:application/json即可 ajax一般默认:Content-Type: application/x-www-form-urlencoded;chars ...

  7. 用ActiveX 创建自己的comboBox 控件(二)

    3.0 添加事件 3.1 添加OnSelChange 事件 当用户选中列表项的时候触发该事件.(不只是选择改变时触发,本次选择和上次相同时也触发): 添加完成后,在ActivexcomboBox.id ...

  8. linux查看文件夹大小du命令

    查看1级(--max-depth=1)目录的大小,并排序 参考 -h或–human-readable 以K,M,G为单位,提高信息的可读性. –max-depth= 超过指定层数的目录后,予以忽略 d ...

  9. AOP方法增强自身内部方法调用无效 SpringCache 例子

    开启注解@EnableCaChing,配置CacheManager,结合注解@Cacheable,@CacheEvit,@CachePut对数据进行缓存操作 缺点:内部调用,非Public方法上使用注 ...

  10. 【转】shell脚本执行时报"bad interpreter: Text file busy"的解决方法

    1)问题现象: 在ubuntu下执行以下脚本( while_count),报错: -bash: ./while_count: /bin/bash: bad interpreter: Text file ...