关于 AprilTag 视觉定位系统

AprilTag 是一个视觉基准库,在 AR、机器人、相机校准领域广泛使用。通过特定的标志(与二维码相似,但是降低了复杂度以满足实时性要求),可以快速地检测标志,并计算相对位置。 第一次接触 AprilTag 是去年智能车室内对弈组的时候了,那时候使用的摄像头硬件是 OpenMV,官方库里就集成了 AprilTag 的识别,在已知相机内参的情况下,单个 AprilTag 就能实现三维空间内的位姿定位。 虽然和 QR 码很像,但 AprilTag 视觉基准码有完全不同的目标和应用场景。使用 QR 码时,通常需要将摄像头与标签对齐,然后以相当高的分辨率拍摄它,获得数百个字节,比如一个网址;相比之下,视觉基准码只承载很小的信息(也许是 12 位),但即使它的分辨率非常低、光线不均匀或隐藏在图像的角落里,也能被自动检测和定位。 官网:https://april.eecs.umich.edu/software/apriltag.html 原理 AprilTag 团队主要的论文有两篇: ICRA 2011 - AprilTag: A robust and flexible visual fiducial system IROS 2016 - AprilTag 2: Efficient and robust fiducial detection 下文从检测器、编码系统两部分过一下原理(其实就是翻译原文)。 使用自然出现的特征一直是机器感知的重点,但人造特征在一些实验中也扮演了很重要的角色,可以简化一些并不关注自然特征的系统。论文设计了一种使用二维码的视觉基准系统,可以从单张图像中实现六个自由度上的定位。这一系统融合了之前的直线检测、数字编码技术,对遮挡、扭曲、镜头失真有更好的效果。 检测器 检测器设计为很低的假阴率,所以就有一个很高的假阳率。(真假表示识别正确与否,阴阳表示识别的结果是真或假,这里就是尽量不漏掉可能的矩形)编码系统会补偿这一过高的假阳率。 直线检测 计算像素的梯度→按照梯度大小排序→以梯度方向作为约束进行聚类→最小二乘计算直线 第一步是从图像中检测直线,方法与 ARTag 检测器的基本方法相似,计算每个像素点的梯度方向和梯度大小,并将像素点聚类成梯度方向和梯度大小相似的分量。 该聚类算法类似于 Felzenszwalb 的基于图的方法:创建一个图,每个节点代表一个像素;在相邻像素之间添加边,边权等于像素在梯度方向上的差值。然后将这些边按边权递增的方式进行排序处理:对于每条边,我们测试其两侧像素所属的集群是否应该连接在一起。 假设一个集群 n,我们把其中像素梯度方向的范围记为 D(n),梯度大小的范围记为 M(n)。也就是说,D(n) 和 M(n) 是标量值,分别表示梯度方向和梯度大小的最大值和最小值之差。对于 D(),必须小心处理 2π周期。然而,由于有用的边的跨度要比π小得多,这就很简单了。 给定 n 和 m 两个集群,如果满足以下两个条件,我们将它们连接在一起: $$D(n \cup m) \leq \min (D(n), D(m))+K_{D} /|n \cup m|$$ $$M(n \cup m) \leq \min (M(n), M(m))+K_{M} /|n \cup m|$$ 这条件可以直观理解:D() 和 M() 值小,表示分量内部变化小。如果两个集群联合起来后的 D() 和 M() 值,与单独的集群差别不大,则将它们连接在一起。参数 KD、KM参数允许分量变化范围适度增加,但随着集群变大,这种裕度会迅速缩小。...

October 29, 2020

Note for “The Python Tutorial” §1~§4

https://docs.python.org/3/tutorial/index.html 尝试读读一手资料,下文主要是翻译 + 摘抄——确实学到很多 §1~§4 主要涉及解释器、基本语法、基本数据类型。 Python 很简单,很强大。高级数据结构,高效的面向对象编程,优雅的语法 elegant syntax,动态类型 dynamic typing,解释性本质 interpreted nature。 Python 的解释器 interpreter 和标准库都能以源代码或二进制形式 source or binary form 获取,还有很多第三方库。 Python 的解释器可以使用 C(或者任何 C 调用的语言 other languages callable from C) 编写的函数和数据结构轻松地扩展。 本教程介绍 Python 最引人注目 noteworthy 的特性,展现这种语言的 flavor and style。 1. Whetting Your Appetite https://docs.python.org/3/tutorial/appetite.html 开胃菜 为什么用 Python?想做一些自动化操作,There’s some task you’d like to automate. 一个专业的软件开发流程,write/compile/test/re-compile cycle,可能感到冗长乏味 tedious。 Unix shell script 脚本适合移动文件、操作数据,不适合 GUI 或游戏;C/C++/Java 开发时间长。Python 更好。 Python 比脚本语言提供更多结构,比 C 提供更多错误检查。作为高等级语言,具有高级数据结构,比如灵活的 array 和 dictionary。...

October 22, 2020

关于 MPU6050 的原理、使用笔记

主要记录一下这两天学到的 IMU 的原理、算法、安装,以及 MPU6050 的 DMP 模式使用。 原理 IMU,Inertial Measurement Unit,全称是惯性导航系统,主要元件有陀螺仪、加速度计和磁力计等。 陀螺仪测量沿 X、Y 和 Z 轴的角位置随时间的变化率,角度需要在此基础上进行积分,主要使用科里奥利效应进行测量;加速度计测量沿 3 个轴的加速度,当 Z 轴向上放置的时候,Z 方向的加速度是+9.8m/s2。 总结来看,常见的力信号转换为电信号的基本方法都是利用电容大小与极板距离的关系,很有意思。 不同传感器有各自的特点,例如陀螺仪有温漂、积分累计误差,加速度计会受震动、物体运动影响,将这些传感器的数据融合,就能得到较为准确的姿态信息。 MPU6050 IMU 在单芯片上集成了一个 3 轴加速度计和一个 3 轴陀螺仪。以及一个可扩展的数字运动处理器 DMP(Digital Motion Processor)。它也被称为六轴运动跟踪设备或 6 DoF 设备,因为它有 6 个输出,即 3 个加速度计输出和 3 个陀螺仪输出。 关于详细原理推荐看 How MEMS Accelerometer Gyroscope Magnetometer Work & Arduino Tutorial,B 站大学也给了翻译版本:MEMS 加速度计陀螺仪磁力仪如何工作+Arduino 教程(中英字幕)[How To Mechatronics];关于性能参数以及 STM32 下的代码(也有 DMP),推荐野火的 第 44 章 MPU6050 传感器—姿态检测。 表达 IMU 获取的是目标物体的姿态,这里就设计到角度的表达方法。 从坐标系开始,这里沿用了一些航空中的定义,但是各种手册、博客、论坛没有统一的标准,大家自己写的时候一定要仔细辨别。...

September 14, 2020

五子棋机器人之手眼标定

来自本学期的《工业机器人系统》课程实验,使用工业机器人实现五子棋人机对弈,同时收录为人类早期战胜 AI 珍贵影像👍 硬件 埃夫特 ER3A-C60 埃夫特紧凑型控制柜 固高示教器 Basler acA1300-30gm 相机 方案 使用吸盘作为工业机器人末端执行器,完成棋子取放工作;使用标定后的工业相机实现定位;使用 OpenCV 的模板匹配实现棋子识别;使用 AlphaZero_Gomoku 方案实现决策系统;使用 3D 打印实现棋子供料(未完成)。 本人在实验中主要负责了相机标定、手眼标定等相关模块,下文针对性地整理记录一些经验,不过多涉及其他部分。 前序知识 (1)世界坐标系(Xw,Yw,Zw):在环境中由用户任意选择一个基准坐标系作为参考来描述摄像机位置,在相机标定中一般选择标定板坐标系作为世界坐标系。 (2)摄像机坐标系(Xc,Yc,Zc):以针孔模型的聚焦中心 O_c(光心)为原点,摄像机光轴为 Z 轴建立三维坐标系,其中 Xc轴、Yc轴与成像平面 x、y 轴平行。光心到图像平面的距离为有效焦距 f。 (3)成像平面坐标系(x,y):光轴与成像平面交点,称为主点。成像平面坐标系以主点为原点,是以物理单位表示的平面直角坐标系。 (4)图像坐标系(u,v):固定在图像上以像素为单位的平面直角坐标系,通常以图像左上角为像素原点,每一像素的(u,v)分别表示该像素在图像数组中的行数和列数。u、v 轴分别与 x、y 轴平行,该坐标系的单位为像素。 相机标定 摄像机采集的是二维图像,需要通过摄像机成像几何模型建立目标物体的 3D 坐标和 2D 图像坐标之间的关系,该模型参数就是摄像机标定所确定的内外参数。 图像坐标系到相机坐标系的转换关系为: $$ Z_{c}\left[\begin{array}{l}u \v \1\end{array}\right]=\left[\begin{array}{ccc}f_{x} & 0 & u_{0} \0 & f_{y} & v_{0} \0 & 0 & 1\end{array}\right]\left[\begin{array}{l}X_{c} \Y_{c} \Z_{c}\end{array}\right] $$ 保持机器人末端位姿不变,手持并改变标定板的位姿,连续拍摄多张照片,导入到 MATLAB 的 Camera Calibrator 工具箱,使用张正友平面法即可标定。...

September 13, 2020

关于 API 的一些基础知识

前两天需要完成一个扫描件转成 Excel 的操作,试了各种 OCR 软件效果都不理想,后来尝试了百度的文字识别 API,5 分钟搞定。看来广告说得对:“学会用 Python,比别人早下班 2 小时。” 🤷‍♂️ 白嫖了好多次百度的 API,但是对各种基础知识都还一知半解,只会对着 Demo 改改。那么现在就从原理出发,花点时间查漏补缺一下吧。 API API(Application Programming Interface,应用程序接口)是一些预先定义的函数,或指软件系统不同组成部分衔接的约定。用来提供应用程序与开发人员基于某软件或硬件得以访问的一组例程,而又无需访问源码,或理解内部工作机制的细节。——百度百科 所以 API 就是指把某些功能封装好,方便其他人调用。而调用的人可以很方便地使用这些功能,并且可以不需要知道这些功能的具体实现过程。 调用 API 流程|CSDN 按照 百度智能云的文档,百度的 API 分为管控型 API(云产品创建、查看、启动停止、扩缩容、释放停止,类似于控制台)和功能型 API(百度语音、人脸识别、文字识别)。 插播一个 SDK 与 API 之间的关系: 你可以把 SDK 想象成一个虚拟的程序包,在这个程序包中有一份做好的软件功能,这份程序包几乎是全封闭的,只有一个小小接口可以联通外界,这个接口就是 API。 比如—— 有一杯密封饮料,它的名字叫做“SDK”。 饮料上插着吸管,吸管的名字叫“API”。 来自:SDK 和 API 的区别? - 简道云的回答 - 知乎 那么说回来,作为用户学习 API 调用的话,其实只需要关注两个部分,即上图中的“请求数据”和“处理并显示”部分,其他内容只管交给开发人员即可。 HTTP 请求 HTTP 的请求与响应,可以称为是 API 请求数据的载体。 按照定义来说,HTTP 就是在网络上传输 HTML 的协议,用于浏览器和服务器的通信。根据 HTTP 标准,HTTP 请求可以使用多种请求方法,其中 GET 和 POST 是最常见的 HTTP 方法。...

July 22, 2020