基于C++OpenCV实现的直线检测、圆检测

资源下载地址:https://download.csdn.net/download/sheziqiong/85627479

实验内容和要求

输入一张彩色图像,要求能够检测出其中的直线、圆。

实验器材

C++ OpenCV 4.5.0 开发平台:Visual Studio 2019 Debug x64

具体实现

3.1 直线检测——利用 Hough 变换

3.1.1 构造 Hough 空间

直线检测的 Hough 空间是对直角坐标系下的(x, y)映射到极坐标系下的(ρ,θ)后,以ρ和θ为轴建立的坐标系空间。映射关系如下图所示:

对于一副大小为 D×D 的图像,通常 ρ 的取值范围为[90,90]。计算方法与直角坐标系中累加器的计算方法相同,最后得到最大的 A 所对应的(ρ,θ)。

3.1.2 边缘检测

我自己实现了 Sobel 算子的检测,但是在面对比较复杂的图形时,效果不是特别好。在此处将 Sobel 边缘检测和 Canny 边缘检测都写出来,并比较结果。

Sobel 算子采用了边缘中心权值为 2 的版本,分别对 x 和 y 方向做了卷积,并且计算了方向。

Canny 边缘检测使用了 OpenCV 自带的函数:先进行一次高斯平滑,掩膜的大小由图像本身大小决定,然后用 Canny 函数进行检测。

在这里插入图片描述

对同一张图片进行两种方法滤波,结果如下:

在这里插入图片描述

左图为自己实现的 Sobel 算子检测结果,运算速度一般;右图为平滑滤波+Canny 检测的结果,运算速度很快。

3.1.3 对边缘点统计,投票,更新累加器

对检测完毕的边缘图像中的“边缘点”,在每一个θ进行遍历,计算出对应的ρ,投票(对应在Hough 空间的累加器里加 1)。

在这里插入图片描述

3.1.4 按照一定的阈值进行输出和绘制

遍历 Hough 空间(累加器),对于最多的交点(也就是比较大的值)处,提取ρ和θ还原原直线信息,并且绘制在图上。

结果分析与改进请见第四部分。

3.2 圆检测——利用 Hough 变换

一个圆的确定需要三个参数:两个参数用来确定圆心,一个参数用来确定半径。

3.2.1 构建 Hough 空间

圆检测的 Hough 累加器可以理解成一个三维数组(空间盒),长宽是原图像的长宽,深度是对半径的预测和累计。对于圆检测首先规定了一个半径的范围,只检测半径长度在该范围内的圆。

在这里插入图片描述

3.2.2 遍历边缘检测图像,统计与投票

对于边缘点,遍历所有可能的半径 r,根据圆的参数方程进行解析,得出两个可以确定圆心的点,对相应的累加器加 1。

3.2.3 根据阈值还原检测圆

在筛选与重现的过程中做了一次根据距离的筛选,即两个圆的圆心之间的距离,以防止很多重复。

实验结果与分析

4.1 直线检测分析

遍历全图的计算量很大,主要是在每一个需要检测的点的余弦值和正弦值的计算,因此在计算之前先对 0 到 180 的所有角度的余弦值和正弦值做了哈希表,用于后面的直接索引。这样一来加速了算法。

在这里插入图片描述

在对一般图片的检测中,呈现出的结果比较良好:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vOg03nK2-1655092296033)(https://www.writebug.com/myres/static/uploads/2022/6/12/9c06e5be879c9f6aa40e1ebb9078ef25.writebug)]

但是对于 highway 这张信息比较复杂的图片,用同样的滤波方式和检测出来的效果却不如人意。除了关键的几条直线被检测出来之外,其他的一些不希望出现的线条也被检测了出来,而且重复性非常大:所以加入了一步非极大值抑制,对累加器的一定邻域内选择最大值输出,减少了冗余的直线。

效果有了很大改观。但是可以看出,对于噪音的鲁棒性不是很好:

4.2 圆检测分析

效果比较好,但是由于设定了圆心之间的距离阈值,所以同心圆无法检测。

心得与体会

这次实验感觉难度比较大,在仔细学习了算法以后,就着手开始自己实现Hough 变换了。遇到了以下几个大问题,被用相应方法自己解决:

  • 运算速度慢——将正弦值和余弦值列哈希表索引以加速;
  • 圆检测的过程中有不希望出现的点被累加器计算——检测是否在原图像范围内,并且对 Hough 空间进行了一次二值化;
  • 直线检测比较杂乱——在不改变阈值的情况下增加非极大值抑制,有一定效果。

但是还有问题,主要是在直线检测方面,对于噪音的影响鲁棒性很差。通过改变高斯滤波算子大小和 Canny 算子大小,甚至是用了形态学变化,效果都不是很好。

这次实验收获很大,自己基本实现了 Hough 变换检测直线和圆的算法,编程能力有了提升,阅读源码的能力也有了提升,同时自己实现了一下 Sobel 算子检测边缘的算法,效果也符合预期。

资源下载地址:https://download.csdn.net/download/sheziqiong/85627479

猜你喜欢

转载自blog.csdn.net/newlw/article/details/125257468