坐标系基础:从世界到像素,再到机器人
做手眼标定,说白了就是搞清楚「眼睛」和「手」之间的位置关系。但在这之前,有个更基础的问题必须解决——坐标系。
我刚开始接触这个领域时,觉得坐标系不就是几个箭头嘛,有什么好讲的?直到第一次做标定,数据怎么都对不上,折腾了两天才发现是图像坐标系和像素坐标系搞混了。嗯,从那以后我再也不敢小看这些基础概念了。
这一章,我们就把六个核心坐标系掰开揉碎讲清楚。你想想看,如果连坐标系的变换都搞不明白,后面的手眼标定矩阵推导、目标检测坐标映射,根本无从下手。
六个核心坐标系,一个都不能少
在实际的机器人视觉系统中,我们通常要面对六个坐标系。它们各自有各自的「地盘」,但最终要能互相通信。
| 坐标系 | 英文缩写 | 核心作用 | 维度 |
|---|---|---|---|
| 世界坐标系 | World | 描述场景中所有物体的位置 | 3D (Xw, Yw, Zw) |
| 相机坐标系 | Camera | 以相机光心为原点,描述物体相对相机的3D位置 | 3D (Xc, Yc, Zc) |
| 图像坐标系 | Image | 物理成像平面上的位置,单位是毫米 | 2D (x, y) |
| 像素坐标系 | Pixel | 图像在计算机内存中的存储位置,单位是像素 | 2D (u, v) |
| 机器人基坐标系 | Base | 固定在机器人底座,描述机器人本体的位置 | 3D (Xb, Yb, Zb) |
| 工具坐标系 | Tool | 固定在机器人末端执行器上,描述工具的位置和姿态 | 3D (Xt, Yt, Zt) |
核心要点:世界坐标系是「全局地图」,相机坐标系是「眼睛看到的」,像素坐标系是「电脑存下来的」,机器人基坐标系是「机器人的根」,工具坐标系是「机器人的手」。手眼标定,就是把这些坐标系串起来。
从3D世界到2D像素:相机成像的四个步骤
相机是怎么把三维世界变成二维照片的?这个过程涉及四个坐标系的连续变换。我个人习惯把这四个步骤记成一条流水线:
- 世界 → 相机:刚体变换(旋转+平移)
- 相机 → 图像:透视投影(小孔成像)
- 图像 → 像素:离散化采样(毫米变像素)
咱们一步步看。
1. 世界坐标系 → 相机坐标系
这一步是刚体变换。说白了,就是把物体在世界中的位置,挪到以相机为原点的坐标系里。
// 齐次坐标形式
| Xc | | R11 R12 R13 Tx | | Xw |
| Yc | = | R21 R22 R23 Ty | | Yw |
| Zc | | R31 R32 R33 Tz | | Zw |
| 1 | | 0 0 0 1 | | 1 |
这里的 R 是 3x3 旋转矩阵,T 是 3x1 平移向量。合起来就是相机的外参矩阵。
我的经验:外参矩阵的物理意义很直观——它告诉你相机在世界中的位置和朝向。我在做移动机器人标定时,经常需要先固定好世界坐标系的原点,比如选在机器人底座正下方,这样后面的计算会省很多事。
2. 相机坐标系 → 图像坐标系
这一步是透视投影,也就是小孔成像模型。
x = f * Xc / Zc
y = f * Yc / Zc
其中 f 是焦距。注意,这里 Zc 不能为0,否则投影无意义。这也是为什么相机不能贴在物体上拍照。
3. 图像坐标系 → 像素坐标系
这一步最容易出错。图像坐标系的单位是毫米,像素坐标系的单位是像素。它们之间差一个缩放和偏移。
u = x / dx + u0
v = y / dy + v0
dx 和 dy 是每个像素在 x 和 y 方向上的物理尺寸,u0、v0 是主点(光轴与成像平面的交点)的像素坐标。
我曾经踩过的坑:有一次标定结果总是偏一个固定偏移,查了半天才发现是 u0、v0 的值给错了。很多相机标定库默认主点在图像中心,但实际传感器可能不是。所以拿到相机参数后,一定要先验证一下主点坐标是否准确。
机器人侧的坐标系:基座标系与工具坐标系
讲完相机侧的四个坐标系,咱们再看看机器人侧的两个坐标系。
机器人基坐标系
这个坐标系固定在机器人底座上,通常是机器人控制器的「世界原点」。所有机器人运动指令,最终都要换算到这个坐标系下执行。
基坐标系的原点一般选在底座安装面的中心,Z 轴向上。不同品牌的机器人可能有细微差别,但大差不差。
工具坐标系
工具坐标系固定在机器人末端法兰盘上。它的原点通常是工具的中心点(TCP, Tool Center Point)。
为什么要单独定义工具坐标系?因为机器人末端可以装不同的工具——夹爪、焊枪、相机。每个工具的 TCP 位置和姿态都不一样。你想想看,如果每次换工具都要重新编程,那效率得多低?
关键概念:手眼标定中,我们通常把相机固定在机器人末端(眼在手上),或者固定在场景中(眼在手外)。无论哪种方式,最终要建立的都是相机坐标系和机器人基坐标系(或工具坐标系)之间的变换关系。
坐标系变换关系总览
为了让你更直观地理解这些坐标系之间的关系,我画了一张图。
变换矩阵的数学本质
所有坐标系之间的变换,在数学上都可以用一个 4x4 的齐次变换矩阵来表示。这个矩阵长这样:
| R11 R12 R13 Tx |
| R21 R22 R23 Ty |
| R31 R32 R33 Tz |
| 0 0 0 1 |
左上角 3x3 是旋转部分,右上角 3x1 是平移部分。为什么用齐次坐标?因为这样可以把旋转和平移统一成一次矩阵乘法,方便连续变换。
举个例子,从世界坐标系到像素坐标系的完整变换:
| u | | fx 0 u0 0 | | R11 R12 R13 Tx | | Xw |
| v | = | 0 fy v0 0 | | R21 R22 R23 Ty | | Yw |
| 1 | | 0 0 1 0 | | R31 R32 R33 Tz | | Zw |
| 0 0 0 1 | | 1 |
前面那个 3x4 矩阵是相机内参矩阵,后面那个 4x4 是外参矩阵。两者相乘,就是完整的投影矩阵 P。
我的建议:刚开始学的时候,不要死记硬背矩阵公式。先理解物理意义——旋转是「转方向」,平移是「挪位置」,内参是「相机自己的参数」,外参是「相机在哪」。理解了这些,公式自然就记住了。
避坑指南:坐标系变换中的常见错误
- 坐标系方向搞反:比如把世界到相机的变换,当成了相机到世界的变换。记住,变换矩阵是有方向的,不能随便颠倒。
- 单位不统一:世界坐标系用米,相机内参用毫米,结果算出来的坐标差三个数量级。我建议所有数据统一用毫米。
- 忽略齐次坐标:有些同学直接用 3x3 旋转矩阵加 3x1 平移向量分开算,结果在连续变换时容易出错。用齐次坐标,一次搞定。
- 工具坐标系没校准:TCP 位置不准,手眼标定结果一定不准。做标定前,先确认工具坐标系是准确的。
我曾经犯过的错:有一次做眼在手上的标定,标定结果看起来很好,重投影误差也很小。但实际抓取时,机器人总是差那么几毫米。查了两天,最后发现是工具坐标系的方向定义和机器人控制器里的定义不一致。从那以后,我每次做标定前都会先打印一份坐标系定义对照表,逐项确认。