AprilTag 入门
文章目录
AprilTag 入门:从一张黑白标签到机器人眼里的坐标
做机器人视觉定位时,经常会遇到一个很朴素的问题:相机看到了目标,但程序怎么知道这个目标在三维空间里的位置和姿态?
AprilTag 就是为这个问题准备的一类视觉标记。它看起来像二维码,但目的不是存储大量信息,而是让机器稳定地识别“这是哪个标签”以及“它相对相机在哪里”。在机器人、机械臂、无人机、移动小车、实验室标定里,它都很常见。
这篇文章结合一个 ROS 2 + MoveIt 2 + 四自由度机械臂的小项目,整理 AprilTag 的入门思路。文章不展开项目代码,只讲概念、流程和容易踩坑的地方,方便后面想把 AprilTag 接进自己项目的人快速上手。
1. AprilTag 是什么
AprilTag 是一种人工视觉标记系统。每个标签都有一个黑白方形图案,检测器可以从图像中识别出它的 ID,并根据相机内参和标签实际尺寸估计出标签相对相机的 6D 位姿,也就是位置加姿态。
简单说:
- 图案告诉程序:这是哪个标签。
- 标签边框告诉程序:这个正方形在图像里怎么变形了。
- 相机内参和标签实际尺寸告诉程序:它离相机多远、朝向如何。
如果只想判断“看没看到某个标记”,AprilTag 可以做到;如果还想让机械臂去靠近它、让小车朝它走、让无人机根据它降落,那就要用到位姿估计。
2. 入门必须理解的几个关键词
Tag family
AprilTag 不是只有一种图案集合,而是分成不同 family,比如 tag36h11、tag25h9 等。
这里的 36h11 可以粗略理解为:标签内部编码更丰富,抗误识别能力比较好,但图案也更细。一般机器人项目里,tag36h11 是很常见、很稳妥的入门选择。
检测器配置的 family 必须和打印出来的标签 family 一致。你打印的是 tag36h11,检测器也要按 36h11 去识别。
Tag ID
同一个 family 里有很多不同 ID 的标签。比如项目里使用的是 tag36h11 家族的 id=0 标签。
ID 的意义是区分目标:如果桌面上贴了多个标签,程序可以通过 ID 判断每个标签分别代表什么位置、物体或工位。
Tag size
这是 AprilTag 入门最容易被忽略、但又最关键的参数。size 指的是标签黑色外边框对应的实际物理边长,单位通常是米。
例如项目里使用的尺寸是 0.10,也就是 10 cm。
这个值会直接影响距离估计。如果你真实标签是 8 cm,却在配置里写成 10 cm,检测出来的位置就会系统性偏差。相机不会凭空知道纸上的标签有多大,这个信息必须由你告诉检测器。
Camera info
AprilTag 要算三维位姿,必须知道相机内参,包括焦距、主点、畸变参数等。在 ROS 里,这些信息通常通过 CameraInfo 消息发布。
如果只有图像,没有相机内参,检测器最多只能知道图像里有一个标签,很难可靠地恢复三维位置。
真实相机建议先完成标定;仿真或合成相机也要提供合理的内参。
TF frame
ROS 里常用 TF 表示坐标系之间的关系。AprilTag 被识别后,检测器通常会发布一个标签坐标系,比如项目里的 tag36h11:0。
后续节点不需要直接处理图像,只要去查 TF,就可以知道:
- 标签相对相机在哪里。
- 标签相对机器人底座在哪里。
- 机械臂末端应该移动到标签前方哪个位置。
这也是 AprilTag 在机器人项目里很舒服的一点:视觉模块负责“看见并发布坐标”,运动模块负责“读取坐标并规划运动”。
3. 一个典型 ROS 2 AprilTag 流程
结合这个项目,可以把 AprilTag 的完整链路抽象成下面几步:
- 准备一张指定 family 和 ID 的标签图像。
- 相机发布图像话题,例如
/camera/image_rect。 - 相机同时发布内参话题,例如
/camera/camera_info。 - AprilTag 检测节点订阅图像和相机内参。
- 检测节点根据配置识别指定 family 的标签。
- 检测成功后,发布对应标签的 TF 坐标系。
- 机械臂、移动机器人或其他业务节点读取 TF,并执行后续任务。
这个项目为了方便验证,没有一开始就依赖真实摄像头,而是使用了一个虚拟相机发布固定的 AprilTag 图像和相机内参。这样做的好处是排除了光照、相机驱动、标定误差等外部因素,先把 ROS 话题、AprilTag 检测、TF 和 MoveIt 规划这条链路跑通。
等虚拟链路稳定后,再替换成真实相机,会更容易定位问题。
4. 项目里的关键配置思路
项目中使用的 AprilTag 识别配置可以概括为:
- 标签 family:
36h11 - 标签实际尺寸:
0.10 m - 识别 ID:
0 - 标签 TF 名称:
tag36h11:0 - 图像话题:
/camera/image_rect - 相机内参话题:
/camera/camera_info
这几个参数基本覆盖了 AprilTag 入门时最重要的配置面。
其中 max_hamming 用来控制容错程度。值越大,越允许图案识别时存在一定误差,但误识别风险也会变高。入门调试时使用较严格的配置更容易排查问题。
z_up 和坐标系朝向有关。做机械臂或导航时,不同库、不同相机光学坐标系、不同机器人底座坐标系的轴向定义可能不一样。看到标签位置“对了但方向怪怪的”时,坐标系方向通常是第一批要检查的对象。
5. 为什么要先用虚拟相机
很多人第一次接 AprilTag,会同时面对这些问题:
- 摄像头能不能正常出图?
- 图像话题名字对不对?
- 相机内参有没有发布?
- 标签 family 配对了吗?
- 标签尺寸写对了吗?
- TF 有没有发布?
- 机器人底座到相机的外参有没有接上?
- MoveIt 规划失败是视觉问题还是运动规划问题?
如果所有东西一起上,很容易分不清是哪一环出了错。
项目使用虚拟 AprilTag 图像,相当于先固定视觉输入。这样可以先验证:
- AprilTag 节点能不能检测到标签。
- 标签 TF 能不能稳定发布。
- 机械臂节点能不能读取标签位姿。
- 规划目标能不能根据标签坐标生成。
这是一种很推荐的开发顺序:先让数据流闭环,再引入真实硬件的不确定性。
6. 真实相机接入时的检查清单
从虚拟相机切换到真实相机时,建议按下面顺序检查。
第一,确认图像话题存在,并且画面里能清楚看到标签。标签不要太小、不要反光、不要严重倾斜,也不要被遮挡。
第二,确认相机内参话题存在。没有 CameraInfo,位姿估计通常会出问题。使用 USB 摄像头时,最好先做一次相机标定。
第三,确认标签打印尺寸和配置尺寸一致。注意这里说的是实际物理边长,不是图片文件的像素大小。
第四,确认 family 和 ID 对得上。打印 tag36h11 就配置 36h11;打印 id=0 就不要在配置里只监听别的 ID。
第五,确认 TF 是否发布。能看到标签 TF,说明检测链路基本跑通;看不到 TF,就先不要急着调机械臂。
第六,确认相机坐标系到机器人坐标系的关系。如果要让机械臂根据标签运动,系统不仅要知道标签相对相机的位置,还要知道相机装在机器人哪里。
7. AprilTag 和机械臂结合时要注意什么
AprilTag 给出的通常是标签坐标系的位置和姿态,但机械臂不能直接“撞到标签中心”。更常见的做法是生成一个接近位姿,比如停在标签前方 15 cm 的位置。
这里会涉及三个坐标概念:
- 标签坐标系:由 AprilTag 检测结果生成。
- 相机坐标系:图像和深度估计的参考。
- 机器人底座坐标系:MoveIt 规划通常使用的世界参考。
机械臂真正需要的是一个在机器人底座坐标系下的目标位姿。也就是说,系统需要通过 TF 把“标签在相机里在哪里”转换成“标签在机器人面前哪里”。
项目里还对 TF 做了多次采样和稳定性判断,这个思路很实用。现实图像会抖动,标签角点检测也会有噪声。如果每一帧都直接驱动机械臂,目标点可能会跳来跳去。先取几次稳定样本,再规划运动,会让系统表现更可靠。
8. 常见问题
能检测到标签,但距离不对
优先检查 size。真实标签边长和配置边长不一致,是距离错误的高频原因。其次检查相机内参是否来自当前相机,而不是复制了别的摄像头参数。
TF 有了,但机械臂运动方向不对
大概率是坐标系关系没理顺。重点看相机光学坐标系、标签坐标系、机器人底座坐标系之间的方向定义,以及相机到机器人底座的外参是否正确。
仿真能跑,真实相机不行
先不要怀疑运动规划。用可视化工具确认真实相机的图像、内参、检测结果和 TF 是否都正常。真实环境里最常见的问题是光照、反光、模糊、内参不准和标签尺寸不一致。
9. 推荐的学习路径
如果你刚开始学 AprilTag,可以按这个顺序来:
- 先只识别单个标签,不接机器人运动。
- 确认检测节点能输出标签 ID 和 TF。
- 用可视化工具观察相机坐标系和标签坐标系。
- 改变标签距离和角度,观察 TF 是否合理变化。
- 再把标签 TF 转换到机器人底座坐标系。
- 最后让机械臂或小车根据这个坐标执行动作。
不要一开始就把相机、机械臂、规划器、控制器、真实环境全部接上。AprilTag 本身不难,难的是把坐标链路接清楚。
10. 小结
AprilTag 的核心价值是:用一张容易打印、容易识别的黑白标签,把视觉问题变成一个清晰的坐标问题。
在 ROS 2 项目里,它通常承担“视觉定位入口”的角色:相机提供图像和内参,AprilTag 检测器发布标签 TF,后面的运动规划或业务逻辑只需要使用这个 TF。
这个项目展示的是一条很适合入门的路线:先用虚拟 AprilTag 图像跑通检测和 TF,再把标签位姿交给 MoveIt 里的机械臂流程。理解这条链路后,再换成真实相机、多个标签、复杂工位,思路也是一样的。
学 AprilTag 最重要的不是记参数,而是记住这句话:图像负责看见,内参负责算准,TF 负责把坐标传给机器人。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)