概要

  • AprilTag视觉定位Python实现
    • AprilTag过程
      • AprilTag边缘检测
      • 四边形检测
      • 编码与解码
    • 实现代码

AprilTag视觉定位Python实现

AprilTag是一个视觉基准库,在AR,机器人,相机校准领域广泛使用。通过特定的标志(与二维码相似,但是降低了复杂度以满足实时性要求),可以快速地检测标志,并计算相对位置。
官网:https://april.eecs.umich.edu/software/apriltag.html

AprilTag过程

AprilTag内容主要包含三个步骤。

  1. 第一步是如何根据梯度检测出图像中的各种边缘。
  2. 第二步即如何在边缘图像中找出需要的四边形图案并进行筛选,AprilTag尽可能的对检测出的边缘检测,首先剔除非直线边缘,在直线边缘进行邻接边缘查找,最终若形成闭环则为检测到一个四边形。
  3. 最后一个步便是如何进行二维码编码和二维码解码,编码方式分为三种,其黑边色块长度分别为8,7,6三个色块长度,对于解码内容,要在检测到的四边形内生成点阵列用于计算每色块的值,再根据局部二值模式(Local Binary Patterns)构造简单分类器对四边形内的色块进行分类,将正例色块编码为1将负例色块编码为0,就可以得到该二维码的编码。得到编码以后再与已知库内的编码进行匹配,确定解码出的二维码是否为正确。

AprilTag边缘检测

对于第一步来说,最主要的功能就是寻找图像中的边缘,原文章使用的是局部二值模式,但是实际使用中,我建议可以使用Canny算子方法,虽然检测出的边缘会减少,但是相应的也降低了图像中的噪点。

四边形检测

对于得到的二值化边缘图像,需要对其进行多边形分析,首先运用
边缘结构分析(Topological structural analysis of digitized binary images)查找多边形,该方法用于确定二值图像边缘的围绕关系,即确定外边缘,内边缘以及它们之间嵌套关系,确定的边缘都与原图都有相对应的关系,因此完全可以用边缘来表示原图。该算法采用编码的思想,首先赋予不同的边缘以不同的编码值,这样方便确认多边形的层次关系。算法从起点开始,编辑边缘的像素,寻找该起始点同类的边缘点,当扫描至起始点时,该多边形闭环形成,切换至下一个起始点重复该操作,直到所有的二值点都被遍历,排除边数小于4的,将满足条件的进行进一步处理。

利用多边形凸包寻找算法(Finding the convex hull of a simple polygon),计算每一个多边形本身的凸包,并求凸包及其多边形的面积,将两个面积进行比较,当多边形面积比凸包大时将该多边形排除,这样子可以有效的排除非凸多边形,以及不满足多边形面积与凸包面积之比大于0.8的多边形,保留满足条件的其余多边形。

对于最终满足条件的多边形,使用道格拉斯-普克算法(Douglas-Peucker algorithm)进行四边形逼近。

1  寻找曲线的两个端点A,B,作曲线间的弦即线段AB。2  求线段AB到曲线上的距离最远的点C,并求其间的距离d。3  将该距离d与提前设定的阈值进行比较,如果小于阈值,就可直接将该直线近似为曲线,该段曲线处理完毕。4  如果距离d大于给定的阈值,用点C将曲线分割成为AC与BC,并分别对两段取线进行1至3的处理。5  当所有曲线都处理完毕时,依次连接各个分割点形成的折线,这样就可将处理前的曲线近似成为直线,排除该情况下顶点数不为4的多边形。


图中表示的就是经过筛选后得到四边形的整个过程。

编码与解码

在上一步检测出的四边形并不一定满足我们的要求,所以需要对上一步得到的四边形进行编码,匹配,检查。对于得到的四边形,首先要确定其内部的点阵,上一步的四边形是以四个顶点的形式进行存储的,根据这四个点可以确定其四边形内的点阵的具体坐标,不同编码方式其点阵的个数不相同(根据选择编码方式不同有8∗8,7∗7,6∗68*8,7*7,6*68∗8,7∗7,6∗6可选),其编码方式由使用者对物体进行标定时确定,根据编码方式的不同,生成不同的内点坐标。以图\ref{矩形编码}所示举例,该二维码的边长为6个黑边,其中的有效编码区域是除去外部黑边的4∗44*44∗4的部分,该部分区域有黑有白,用于二维码的编码。

具体的编码方式如下:

在确定的四边形中明确点阵坐标,在灰度图像中提取点阵的最外围一圈的像素的平均值Value1,再提取点阵次外外围一圈的像素的平均值Value2,根据AprilTag本身的二维码库的设计,四边形最外一层的虽有点的灰度值都是黑色的,而此外层的灰度值是黑色与白色混合,因此在同一光照环境下,Value1和Value2有明显的阈值分界线,确定阈值为Value1与Value2的均值,重新遍历整个点阵所有点坐标的像素值高于阈值的部分编码为0,低于阈值的部分编码为1,见图\ref{图片点阵}。如此以来,从第一行开始进行编码,直至整个点阵被编码完成,将编码排列起来会得到一串二进制码,该二进制码的长度由具体的编码方式决定(分为36,25,16三种),每个四边形都能得到一串二进制码,该码表示该状态下二维码的编码,错误的四边形往往会生成错误的编码,错误编码无法在阈值范围内匹配到相应的ID,故可以轻松的排除错误编码的四边形,对得到的四边形进行编码并进行匹配校验是重要的一个过程。

进一步确定编码是否可靠,要与已知的编码库进行匹配,由于观察到的编码存在旋转的情况,所以应先将得到的编码进行三次90°旋转共得到四个方向上的编码,再逐一与编码库进行比较,求解编码之间的汉明距离(Hamming Distance,汉明距离是表示两个二进制编码之间的相似程度的一种距离,汉明距离是两个长二进制串之间位数不相同的个数。当观察编码与已知库里的某一编码的汉明距离小于给定的阈值时(一般为2),就确定该观察编码的ID为与之匹配的编码库里的ID,并记录下该汉明距离,若编码库并没有一个与之匹配就确定该观察编码有误,则舍弃该编码对应的四边形。

经过上述的筛选与验证,至此观察编码的ID以及编码的旋转已经可以确定,便可计算该二维码的其他参数,包括二维码相对于原二维码的旋转方位,观察二维码与匹配二维码的相似程度,其中主要为二维码的单线性变换矩阵(Homography Matrix)},在计算机领域中的针孔相机模型下,同一个张图形在不同空间内都有相关性,单线性变换就是将这个图片在该空间下映射至另一个与之对应的空间下,单线性变化矩阵就是这种映射矩阵且可分解出寻转矩阵与平移矩阵,根据上一个步骤求出的四个顶点的坐标即可求出相对于原始坐标的单线性变换矩阵,利用单线性变换矩阵结合多相机的信息,可以得到二维码的相关姿势信息。分解该矩阵就可求出旋转变换向量rvec以及平移变换向量tvec,对于得到的旋转向量,可以根据该向量求得二维码的正确姿势。

实现代码

这个算法是一个开源算法。
原始C代码地址为:https://april.eecs.umich.edu/software/apriltag
我个人将它重构为C#代码:https://github.com/BlackJocker1995/Apriltagcsharp
python代码:https://github.com/BlackJocker1995/Apriltag_python

Apriltag原理简介及源代码相关推荐

  1. javascript原理_JavaScript程序包管理器工作原理简介

    javascript原理 by Shubheksha 通过Shubheksha JavaScript程序包管理器工作原理简介 (An introduction to how JavaScript pa ...

  2. Linux安全原理简介

    Linux安全原理简介 介绍 在设置Linux计算机的所有阶段,安全性应是首要考虑之一.要在计算机上实施良好的安全策略,需要对Linux的基础知识以及所使用的某些应用程序和协议有充分的了解. Linu ...

  3. Xposed原理简介及其精简化

    Xposed原理简介及其精简化 Xposed是⼀个很强⼤的Android平台上的HOOK⼯具,⽽且作者为了⽅便开发者使⽤开发了⼀个APP(Xposed Installer,下⽂称为Installer) ...

  4. Nginx 反向代理工作原理简介与配置详解

    Nginx 反向代理工作原理简介与配置详解 测试环境 CentOS 6.8-x86_64 nginx-1.10.0 下载地址:http://nginx.org/en/download.html 安装 ...

  5. DeepLearning tutorial(1)Softmax回归原理简介+代码详解

    FROM: http://blog.csdn.net/u012162613/article/details/43157801 DeepLearning tutorial(1)Softmax回归原理简介 ...

  6. DeepLearning tutorial(3)MLP多层感知机原理简介+代码详解

    FROM:http://blog.csdn.net/u012162613/article/details/43221829 @author:wepon @blog:http://blog.csdn.n ...

  7. DeepLearning tutorial(4)CNN卷积神经网络原理简介+代码详解

    FROM: http://blog.csdn.net/u012162613/article/details/43225445 DeepLearning tutorial(4)CNN卷积神经网络原理简介 ...

  8. 【Android 异步操作】Handler ( 主线程中的 Handler 与 Looper | Handler 原理简介 )

    文章目录 一.主线程中的 Handler 与 Looper 二.Handler 原理简介 一.主线程中的 Handler 与 Looper Android 系统中 , 点击图标启动一个应用进程 , 就 ...

  9. 量子计算机编程原理简介 和 机器学习

    量子计算机编程原理简介 和 机器学习 本文翻译自D-Wave公司网站 www.dwavesys.com/en/dev-tutorial-intro.html D-wave公司在2007年就声称实现了1 ...

最新文章

  1. 怎样在Github参与一个开源项目
  2. hdu_1007_Quoit Design(最近点对)
  3. Solr Facet(分片)
  4. php手册最新版本_PHP官方网站及PHP手册
  5. IOS开发之MD5加密和钥匙串的使用-oc
  6. 泛型(CSDN转载)
  7. 信息学奥赛一本通(2047:【例5.16】过滤空格)
  8. 环境安装_Python教程 Python环境安装
  9. mysql比较varchar值大小_Mysql varchar大小长度问题
  10. ShellExecute的各种用法 [转帖于 2009-05-020 21:15]
  11. 揭秘你所看不见的技术原理 - 广告推荐系统
  12. Xcom传送文件实例
  13. Spring周期总结
  14. Windows 10推送的锁屏壁纸保存方法
  15. 小程序各个文件夹的作用分类
  16. NBUT 1225 NEW RDSP MODE I (规律+快速幂)
  17. 雷军演讲刷屏,我对项目经理人的发展又有了2点想法……
  18. UE4(一):游戏起点流程图
  19. Unity 获取手机键盘弹出高度
  20. 数据分析实战——星巴克门店数量可视化分析

热门文章

  1. [矩阵论]Jordan标准形中Jordan块阶数与个数的确定
  2. GitBook在Windows下安装部署
  3. Essay-IT学习方法论
  4. SQLite管理软件 - SQLite Developer
  5. 智课雅思词汇---二十一、名词性后缀acity是什么意思
  6. 如何清零爱普生调整程序和重置工具– L365,L360,L310,L220,L130
  7. 王道数据结构代码——线性表
  8. 百度上传网站服务器地址,用浏览器访问 一个网站(www.baidu.com) 的过程
  9. 【堡垒机测评】关于纽盾堡垒机、jumpserver堡垒机、行云管家堡垒机的使用对比
  10. 让你工作效率翻倍的神器