OpenCV4.0.0正式release了,其中加入了二维码识别功能,有幸博主最近开始折腾二维码识别,发现二维码的核心就是那三个定位点和辅助对齐点。ZXing和OpenCV都是通过二维码定位点的11311来进行定位的,这是利用了二维码最显著的特征。但是博主会处理一些变态的情况,比如过曝光到11311定位点无法找到(即图像中定位点的黑白间隔不是1:1:3:1:1),于是就需要通过其它方法来找定位点了。一个标志识别库摆在眼前:AprilTag。(OpenCV中集成了类似的库,似乎叫做ARTag,没研究过)
AprilTag诞生于2011年的一篇论文,2016年出了AprilTag2,但是16年的论文感觉没讲啥,再加上看的cpp代码是2013年的,于是这篇博客就对着2013版本来讲好了,我们开始吧。
一、论文、代码、概述
博主接触过的Marker识别还挺多的,用过比较好的就是随机点Marker,然后就是AprilTag这种Marker,它们都具备一定的抗遮挡能力,可以被用作视觉定位、相机标定等。AprilTag就是具有编码信息的那种。
官网:https://april.eecs.umich.edu/software/apriltag.html
AprilTag论文: url=”https://pcv.oss-cn-shanghai.aliyuncs.com/wp-content/upload/2018/11/olson2010tags.pdf“
AprilTag2论文:url=”https://pcv.oss-cn-shanghai.aliyuncs.com/wp-content/upload/2018/11/wang2016iros.pdf“
还有一篇用它来做相机标定的论文:url=”https://pcv.oss-cn-shanghai.aliyuncs.com/wp-content/upload/2018/11/richardson2013iros.pdf“
这份c++代码
AprilTag-cpp:
swatbotics / apriltags-cpp
C++ port of the AprilTags library, using OpenCV (and optionally, CGAL)
ApriTag-cpp-win: 这是博主fork上面的,稍作适配性修改,可以直接在Windows下编译,
P-Chao / apriltags-cpp-win
[Windows Version: AprilTag] C++ port of the AprilTags library, using OpenCV (and optionally, CGAL)
二、AprilTag的检测流程
2010年的那篇Paper基本描述了处理细节
1. 读入原图,做图像预处理
3. 计算梯度,包含梯度的方向和幅值
这里在计算得到梯度后,选取幅值M大于阈值的作为边缘点
4. 对梯度边缘进行聚类(使用并查集)
对于边缘点,搜索其周围点,根据边缘的方向,将相邻的点进行聚类,其中使用了并查集(常被用来标注连通域)
5. 采用线性回归拟合直线
6. 寻找封闭直线组成的四边形(DFS四层)
7. 细化
三、AprilTag的解码细节
根据AprilTag设计的码型,仿射变换回正视之后,来对其进行网格采样,几种常用的码型如下,有一些码型带有校验功能,所以具备一定的抗遮挡能力
2010年的那篇论文里面有细节。这里在对7×7的module进行采样时,最外圈是白色,外圈里面的一小圈是黑色,所以根据这两圈的采样来确定二值化阈值。对黑模块和白模块分别用二次多项式来拟合灰度分布(考虑到自然界中材质、光源等特性,反光强度常常是凸函数),对于每个位置,都将计算黑白模块应该在这里是多少阈值,就选择黑色点的灰度分布方程和白色点的灰度分布方程,算出两个灰度,选中间值作为阈值。
2. 计算单应矩阵
因为Marker是正方形,所以假定四边形都是homography之后的。
Homography
四、用于相机标定或位姿测量
主要是2013年那篇paper里面的。挖坑回填?如果有时间的话,欢迎下方留言。
非常感谢博主的分享,请问您在“检测流程”部分放上的图是您怎样实现的呢?就是用的源码吗?摄像头等硬件设备您是如何调用的呢?
我也想通过Apriltag来实现定位,非常想跟您学习一下。
网上用openmv的视觉模块,但是在单片机上怎么运行的我不会,能不能交流一下。
单片机有操作系统吗?
源码里面cmake之后有几个vs工程,参考下
我也想自己用单片机做apriltag定位,希望和大神交流,我的qq:1137945746
大神,我也想和你交流。我的qq:591791945。谢谢您!
大神,有一些问题想向你请教,我的qq644534561,谢谢。
大神,我仅仅想用Apriltag来识别tag码并得到四个角点的值,请问该怎么做呢
读一下主函数demo代码,里面有一个四边形检测,做到这一步就有四个角点位置了