2、标定概念与坐标系:世界坐标系、相机坐标系、图像坐标系、像素坐标系的关系与转换
做标定这么多年,我见过太多人一上来就调参、跑算法,结果标出来误差大得离谱。为什么?说白了,就是没搞懂坐标系是怎么转的。你连像素点在世界里对应哪个位置都说不清,标定怎么可能准?
这一章,咱们就把四个坐标系的关系彻底捋清楚。我保证,看完你就能自己手推转换公式。
2.1 四个坐标系,一个都不能少
先问个问题:一张图像上的像素点,怎么对应到现实世界中的某个位置?
答案是——经过四次坐标变换。每次变换都对应一个坐标系。我习惯把它们分成两组:
- 物理世界组:世界坐标系、相机坐标系
- 成像平面组:图像坐标系、像素坐标系
下面这张图,是我自己画的结构关系,你看一眼就能明白整体脉络:
2.2 世界坐标系 → 相机坐标系:刚体变换
世界坐标系是你自己定的。你可以把原点放在标定板的角点上,也可以放在机器人基座上。相机坐标系的原点在相机光心,Z轴沿着光轴方向。
从世界坐标到相机坐标,说白了就是一次旋转加一次平移。数学上叫刚体变换:
|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] [ ] [Zw]
[1 ] [0 0 1] [1 ]
这里的 R 和 t 就是外参。标定要解的第一个东西。
我的经验:外参的旋转矩阵 R 有 9 个元素,但自由度只有 3(绕 X、Y、Z 轴的旋转角)。实际标定时,我习惯用罗德里格斯公式把旋转向量转成矩阵,数值稳定性更好。
2.3 相机坐标系 → 图像坐标系:透视投影
这一步是核心中的核心。相机坐标系下的点 (Xc, Yc, Zc),通过小孔成像模型投影到成像平面上。
公式很简单:
x = f * Xc / Zc
y = f * Yc / Zc
其中 f 是焦距(单位:毫米)。注意,这里 Zc 不能为 0,否则投影无意义。
写成矩阵形式:
|x| |f 0 0 0| |Xc|
|y| = |0 f 0 0| |Yc|
|1| |0 0 1 0| |Zc|
|1 |
⚠️ 容易踩的坑:我曾经遇到过一台线扫相机,投影出来的图像总是有拉伸。查了半天,发现是镜头焦距标称值和实际值差了 0.3mm。别迷信镜头上的刻字,标定出来的才是真的。
2.4 图像坐标系 → 像素坐标系:离散化
图像坐标系 (x, y) 的单位是毫米,是连续的。但传感器是离散的像素阵列,所以需要转成像素坐标 (u, v)。
转换关系:
u = x / dx + u0
v = y / dy + v0
其中:
- dx, dy:每个像素在 x、y 方向的物理尺寸(毫米/像素)
- u0, v0:图像中心(主点)的像素坐标
齐次形式:
|u| |1/dx 0 u0| |x|
|v| = | 0 1/dy v0| |y|
|1| | 0 0 1 | |1|
2.5 合在一起:完整的投影方程
把上面三步串起来,就是完整的从世界坐标到像素坐标的投影:
|u| |fx 0 u0 0| |R t| |Xw|
|v| = | 0 fy v0 0| | | |Yw|
|1| | 0 0 1 0| |0 0 1| |Zw|
|1 |
其中 fx = f/dx,fy = f/dy,单位是像素。
这个 3×4 的矩阵,就是投影矩阵 P。标定的本质,就是解出 P 矩阵中的参数。
一句话总结:世界坐标到像素坐标,就是“外参(R,t)把点转到相机系,内参(fx,fy,u0,v0)把点投到像素面”。标定就是反着来——从已知的像素点和世界点,反推这些参数。
2.6 四个坐标系的参数对比
| 坐标系 | 符号 | 单位 | 维度 | 关键参数 |
|---|---|---|---|---|
| 世界坐标系 | (Xw, Yw, Zw) | 毫米 | 3D | 自定义原点 |
| 相机坐标系 | (Xc, Yc, Zc) | 毫米 | 3D | R, t(外参) |
| 图像坐标系 | (x, y) | 毫米 | 2D | f(焦距) |
| 像素坐标系 | (u, v) | 像素 | 2D | fx, fy, u0, v0(内参) |
2.7 线扫相机的特殊之处
四线扫相机和普通面阵相机最大的区别在哪?
普通相机一次拍一张二维图像。线扫相机一次只拍一行像素,靠物体运动或相机运动来拼出整张图。
这意味着什么?
- 图像坐标系只有一行:y 方向的信息来自运动,不是来自传感器本身
- 需要额外的运动轴标定:编码器脉冲当量、运动方向与相机坐标系的夹角,都得标
- 外参中的 t 不再是固定值:每行图像的 t 都在变,因为相机和物体在相对运动
我的做法:标定四线扫相机时,我会把运动轴当成一个额外的“时间维度”加入坐标系转换链。这样,世界坐标到像素坐标的映射就变成了 4D→2D 的映射。听起来复杂,但原理和单相机标定一模一样。
2.8 避坑指南:坐标系转换中的常见错误
- 主点不在图像中心:别想当然认为 u0, v0 就是图像宽高的一半。实际镜头装配有偏差,主点可能偏好几个像素。
- dx 和 dy 不相等:像素不一定是正方形。我遇到过传感器像素是 5.5μm × 5.5μm 的,但标出来 dx 和 dy 差了 0.02μm——这就是制造公差。
- Zc 的符号:相机坐标系下,物体在相机前方,Zc 应该是正值。如果标出来 Zc 是负的,检查一下你的坐标轴方向定义。
- 旋转矩阵的正交性:解出来的 R 矩阵可能不满足 R^T R = I。需要做正交化处理,否则后续计算会出问题。
⚠️ 我曾经踩过的坑:有一次标定结果反复验证都不对,误差一直在 5 个像素以上。折腾了两天,最后发现是标定板上的角点序号和世界坐标对应错了。低级错误,但最容易忽略。标定前,一定先确认对应关系。