当前位置:   article > 正文

OpenCV2学习笔记(七):使用Canny算子检测轮廓

OpenCV2学习笔记(七):使用Canny算子检测轮廓

在:http://blog.csdn.net/liyuefeilong/article/details/43927909 中,主要讨论了使用sobel算子和拉普拉斯变换进行边缘检测。其中主要使用了了对梯度大小进行阈值化以得到二值的边缘图像的方法。在一幅图像中,边缘往往包含着重要的视觉信息,因为它们描绘出图像元素的轮廓。然而,仅仅使用简单的二值边缘图像有两大缺陷:

1. 使用这种方法检测得到的边缘过粗,这意味着难以实现物体的精确定位。

2. 难以找到这样的阀值,既能足够低检测到所有重要的边缘,同时也不至于包含过多次要的边缘。

这两个问题正是此节所使用的Canny算法所要尝试解决的。Canny算子是JohnCanny于1986年提出的,它与Marr(LoG)边缘检测方法类似,属于先平滑后求导数的方法。

Canny算子通常基于Sobel算子(当然,也可以使用其他的梯度算子)。一般来说,图像梯度幅值矩阵中的元素值越大,说明图像中该像素点的梯度值越大,但这并不能说明该点就是边缘。在Canny算法中,非极大值抑制是进行边缘检测的重要步骤,通俗意义上是指寻找像素点局部最大值,将非极大值点所对应的灰度值置为0,这样可以剔除掉一大部分非边缘的点。较高的亮度梯度比较有可能是边缘,但是没有一个确切的值来限定多大的亮度梯度是边缘多大又不是,所以 Canny使用了磁滞阀值化的策略:

1. 磁滞阀值化的原理是使用高与低两个阈值。假设图像中的重要边缘都是连续的曲线,这样就可以跟踪给定曲线中模糊的部分,并且避免将没有组成曲线的噪声像素当成边缘。所以使用一个较大的阈值,标识出比较确信的真实边缘,使用前面导出的方向信息,从这些真正的边缘开始在图像中跟踪整个的边缘。

2. 在跟踪的时候,我们使用一个较小的阈值,这样就可以跟踪曲线的模糊部分直到我们回到起点。这样根据两个阈值分别进行划分,得到两幅边缘图。

3. Canny算法组合两幅边缘图以生成一副“最优”的轮廓图。如果存在连续的边缘点,则将低阀值图像中的边缘点与高阀值图像中的边缘相连接,那么就保留低阀值图像中的边缘点。

Canny算法通常处理的图像为灰度图,因此若输入的是彩色图像,则需要进行灰度化。对于RGB图像,通常灰度化采用的方法主要有:
1. Gray=(R+G+B)/3;
2. Gray=0.299R+0.587G+0.114B;(这种参数考虑到了人眼的生理特点)
注意,在程序设计时要考虑到图像格式中RGB的顺序通常为BGR。然而,opencv支持将输入图像直接转化为灰度图像,因此可以跳过这个步骤。

Canny算法对于两个阈值的选择有一定的要求。对于较低那个阈值,应该包括所有被认为是属于明显图像轮廓的边缘像素。而较高的阈值的角色应该是定义属于所有重要轮廓的边缘,它应该排除所有异常值。

在OpenCV中,实现Canny算法的函数是cv::Canny,首先需要知道的是,cv::Canny的两个阈值都需要用户亲自输入,且使用的边缘梯度是用sobel算子,该函数的调用方法如下:

cv::contours; 
cv::Canny(image,     // 输入的灰度图像
      contours,  // 输出轮廓
      125,       // 低阈值
      200);      // 高阈值
  • 1
  • 2
  • 3
  • 4
  • 5

首先创建一个Qt控制台项目,并新建一个名为Canny算法的类,修改canny.h:

#ifndef CANNY_H
#define CANNY_H

  • 1
  • 2
  • 3
  • 4
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/173480
推荐阅读
相关标签
  

闽ICP备14008679号