矩形检出算法介绍

背景

矩形检出算法即从一副图像中找出候选矩形,不同于hough找圆等算法在opencv中有现成接口,矩形检出算法需要自己手动实现。其常见用途是移动端拍摄文档进行矫正等,近期开发二维码识别时也用到了矩形检出的算法,在此一并做个总结。

常规算法

常规算法也是最直观、大家都能想到的算法(此处搬运别人公众号的内容:https://mp.weixin.qq.com/s/mkRjgQ8XY4L73ovVjF55EQ),其算法流程如下:

1.中值滤波去噪;

2.依次提取不同的颜色通道(BGR)检测矩形;

3.对每一通道使用canny检测边缘或者使用多个阈值二值化;

4.使用findContours函数查找轮廓;

5.使用approxPolyDP函数去除多边形轮廓一些小的波折;

6.找到同时满足面积较大和形状为凸的四边形;

7.判断轮廓中两两邻接直线夹角余弦是否小于0.3(意味着角度在90度附近),是则此四边形为找到的矩形。

此算法仅对边缘区分明显,仅需要找出最外层的矩形时候有效,在矩形区域发生重叠、存在包含关系时便不鲁棒了。

Apriltag中的算法

Apriltag是密西根大学开源的一个视觉基准库,长用于无人机、移动机器人的自主定位,详细原理请见其官网和3篇paper(https://april.eecs.umich.edu/software/apriltag.html)。

在Apriltag中,检出矩形的算法也分两种,一种是类似上述的常规算法,其封装的函数为getQuads_MZ(),先进行局部自适应二值化、然后找轮廓、计算凸包、找出最大内接矩形。不知为何,Apriltag中默认使用的是另一种检出矩形的方法,其封装的函数为getQuads_AT(),先对此函数中的算法进行分析:

1、高斯模糊;

2、计算图像梯度,此处类似sobel算子,但其计算的梯度包含了方向和幅值,选择大于阈值的像素点作为边缘点;

3、分割、合并获得的边缘;

4、对梯度边缘进行聚类;

5、线性回归拟合直线;

6、dfs4次查找封闭直线组成的四边形

(这部分内容,参见apriltag源码和博客http://www.p-chao.com/2018-11-23/apriltag%E6%A0%87%E5%BF%97%E8%AF%86%E5%88%AB/)。

需说明的是,apriltag会找出很多候选四边形,需要根据长宽比、角度等特征对候选四边形进行筛选。

hed方法

上述介绍的两种算法都是典型的传统算法,其检测边缘点阈值等参数需要人为设定经验值,在面对边缘梯度不明显等场景时表现往往不佳。HED边缘检测算法源自ICCV2015,由于目前对神经网络缺乏了解,此处直接搬运别人博客的内容(https://www.cnblogs.com/damumu/p/7320368.html)。

[转]opencv基于hed边缘检测实现的矩形检出
这里写图片描述 
按照编号顺序,几个关键步骤做了下面这些事情:

用 HED 网络检测边缘,可以看到,这里得到的边缘线还是存在一些干扰的 
在前一步得到的图像上,使用 HoughLinesP 函数检测线段(蓝色线段) 
把前一步得到的线段延长成直线(绿色直线) 
在第二步中检测到的线段,有一些是很接近的,或者有些短线段是可以连接成一条更长的线段的,所以可以采用一些策略把它们合并到一起,这个时候,就要借助第三步中得到的直线。定义一种策略判断两条直线是否相等,当遇到相等的两条直线时,把这两条直线各自对应的线段再合并或连接成一条线段。这一步完成后,后面的步骤就只需要蓝色的线段而不需要绿色的直线了 
根据第四步得到的线段,计算它们之间的交叉点,临近的交叉点也可以合并,同时,把每一个交叉点和产生这个交叉点的线段也要关联在一起(每一个蓝色的点,都有一组红色的线段和它关联) 
对于第五步得到的所有交叉点,每次取出其中的 4 个,判断这 4 个点组成的四边形是否是一个合理的矩形(有透视变换效果的矩形),除了常规的判断策略,比如角度、边长的比值之外,还有一个判断条件就是每条边是否可以和第五步中得到的对应的点的关联线段重合,如果不能重合,则这个四边形就不太可能是我们期望检测出来的矩形 
经过第六步的过滤后,如果得到了多个四边形,可以再使用一个简单的过滤策略,比如排序找出周长或面积最大的矩形 。

总结

第一种常规算法在普通场景下还可以工作,也是最容易实现的,但稍微复杂可能就无法应对。第二种apriltag中的方法可以满足大多数场景下的应用,但需要对检出的诸多四边形进行筛选。最后一种基于hed网络实现的矩形检出算法在面向拍摄文档进行处理的场景比较鲁棒。

不足之处,请多多指正。

猜你喜欢

转载自blog.csdn.net/happyjume/article/details/85699573