3. 坐标系与变换
做视觉标定,说白了就是在玩坐标系。你想想看,一个三维空间里的点,要变成照片上的一个像素,中间要经历多少层“翻译”?我刚开始接触这行时,总觉得这些坐标系很抽象,直到有一次在现场调一个机械臂抓取项目,标定参数算错了,机器人直接抓了个空。嗯,从那以后,我对坐标系变换再也不敢马虎了。
这一章,我们就来把这四个坐标系之间的变换关系彻底理清楚。你掌握了这个,标定的底层逻辑就通了。
3.1 四个坐标系,各司其职
先认识一下这四位“主角”。它们各自负责一个环节,缺一不可。
| 坐标系 | 英文简称 | 维度 | 作用 |
|---|---|---|---|
| 世界坐标系 | World | 3D (Xw, Yw, Zw) | 描述物体在真实世界中的位置,是全局基准 |
| 相机坐标系 | Camera | 3D (Xc, Yc, Zc) | 以相机光心为原点,描述物体相对于相机的位置 |
| 图像坐标系 | Image | 2D (x, y) | 在成像平面上,以物理单位(毫米)表示投影位置 |
| 像素坐标系 | Pixel | 2D (u, v) | 在图像上,以像素为单位,描述行列位置 |
我个人习惯把整个变换过程想象成一条流水线:世界上的一个点,先通过刚体变换转到相机坐标系下,再通过投影变换落到成像平面上,最后通过仿射变换变成像素坐标。
3.2 刚体变换:从世界到相机
刚体变换,说白了就是旋转加平移。物体本身不会变形,只是换个角度看它。从世界坐标系到相机坐标系,就是这个关系。
数学表达式很简单:
|Xc| | R11 R12 R13 | |Xw| |Tx|
|Yc| = | R21 R22 R23 | |Yw| + |Ty|
|Zc| | R31 R32 R33 | |Zw| |Tz|
写成齐次坐标形式,更简洁:
|Xc| | R T | |Xw|
|Yc| = | | |Yw|
|Zc| | 0 1 | |Zw|
|1 | |1 |
这里的 R 是 3x3 旋转矩阵,T 是 3x1 平移向量。它们合起来就是相机的外参。
3.3 投影变换:从相机到图像
这一步是“从3D到2D”的关键。相机坐标系下的点,通过小孔成像模型,投影到成像平面上。
公式很直观:
x = f * Xc / Zc
y = f * Yc / Zc
其中 f 是焦距。你看,Zc 被除掉了,深度信息在这一步丢失了。这也是为什么单张图片无法直接恢复三维深度——你想想看,一个近处的小物体和一个远处的大物体,可能在图像上投影成同样大小。
用齐次坐标写:
|x| | f 0 0 0 | |Xc|
|y| = | 0 f 0 0 | |Yc|
|1| | 0 0 1 0 | |Zc|
|1 |
3.4 仿射变换:从图像到像素
成像平面上的物理坐标 (x, y) 最终要变成我们看到的像素 (u, v)。这一步涉及两个因素:
- 缩放: 像素的物理尺寸 (dx, dy),单位是 mm/pixel
- 偏移: 主点 (u0, v0),即光轴与成像平面的交点
公式:
u = x / dx + u0
v = y / dy + v0
齐次坐标形式:
|u| | 1/dx 0 u0 | |x|
|v| = | 0 1/dy v0 | |y|
|1| | 0 0 1 | |1|
这部分参数,加上焦距 f,统称为相机的内参。
3.5 完整变换链:一张图看懂
把上面三步串起来,就是完整的变换过程。我画了一张图,帮你把整个逻辑串起来。
3.6 综合变换公式
把上面三步合并,就得到了从世界坐标到像素坐标的完整公式:
|u| | fx 0 u0 0 | | R T | |Xw|
|v| = | 0 fy v0 0 | | | |Yw|
|1| | 0 0 1 0 | | 0 1 | |Zw|
| | |1 |
其中 fx = f/dx,fy = f/dy。这个 3x4 的矩阵,就是相机的投影矩阵 P。
3.7 避坑指南:我踩过的几个坑
- 坐标系方向搞反: 我曾经在定义世界坐标系时,把Z轴方向搞反了,结果标定出来的外参旋转矩阵全是错的。后来我养成了一个习惯:标定前先用一张棋盘格,手动验证一下坐标轴方向。
- 齐次坐标忘记加1: 写代码时容易把世界坐标写成 (Xw, Yw, Zw) 而不是 (Xw, Yw, Zw, 1)。这个低级错误会导致矩阵乘法维度不匹配,结果全乱套。
- 忽略畸变模型: 很多初学者只标定内参外参,不做畸变校正。结果投影误差很大。记住,畸变参数也是内参的一部分,必须一起标定。
好了,坐标系变换这块内容,说白了就是“世界→相机→图像→像素”这条链。你把这个链条刻在脑子里,后面的标定算法就很好理解了。