2、成像模型与坐标系:像素坐标系、图像坐标系、相机坐标系、世界坐标系
做线扫相机标定,绕不开坐标系。说白了,你看到的每一张图像,背后都藏着四个坐标系在来回变换。我刚开始接触这行时,也被这些坐标绕得头晕。后来亲手调过几套线扫系统,才慢慢摸清它们的脾气。
今天咱们就把这四个坐标系彻底捋清楚。你想想看,相机拍到的像素点,怎么变成真实世界里的物理位置?中间经历了什么?这就是本节要讲的核心。
2.1 四个坐标系,一个都不能少
先给个全景图。四个坐标系分别是:
- 像素坐标系:图像上的行列号,单位是像素 (pixel)
- 图像坐标系:成像平面上的物理位置,单位是毫米 (mm)
- 相机坐标系:以相机光心为原点的三维坐标系,单位是毫米 (mm)
- 世界坐标系:你自定义的全局参考系,单位是毫米 (mm)
它们的关系就像一条流水线:世界坐标 → 相机坐标 → 图像坐标 → 像素坐标。标定的本质,就是求出这条流水线上每一步的转换参数。
核心观点:标定不是目的,建立从像素到世界的映射才是。你标定出来的参数,就是这条映射链上的钥匙。
2.2 像素坐标系 vs 图像坐标系
这两个最容易搞混。我见过不少新手,上来就把像素坐标当物理坐标用,结果标定出来的参数全是错的。
像素坐标系 (u, v):原点在图像左上角,u 轴向右,v 轴向下。单位是像素。说白了,就是告诉你「这个点在第几行第几列」。
图像坐标系 (x, y):原点在光轴与成像平面的交点(主点),x 轴向右,y 轴向下。单位是毫米。它描述的是「成像平面上的实际物理位置」。
转换关系很简单:
x = (u - cx) * dx
y = (v - cy) * dy
其中 (cx, cy) 是主点像素坐标,dx、dy 是每个像素的物理尺寸(mm/pixel)。
我的习惯:做线扫标定时,我一般先确认 dx 的值。线扫相机的像元尺寸通常是 5μm、7μm 或 10μm,这个数据直接决定了你的测量精度上限。
2.3 相机坐标系:从 2D 回到 3D
相机坐标系的原点在光心,Zc 轴沿着光轴指向被摄物体,Xc 轴向右,Yc 轴向下。这是一个三维坐标系。
从相机坐标到图像坐标,用的是针孔成像模型:
x = f * Xc / Zc
y = f * Yc / Zc
这里 f 是焦距(mm)。你看,深度 Zc 被除掉了,三维信息压缩成了二维。这也是为什么单张图像无法直接恢复深度——信息丢了。
我曾经踩过的坑:线扫相机不是面阵相机,它的成像模型略有不同。线扫只有一行传感器,另一维靠运动平台补。所以 Zc 方向上的精度,很大程度上取决于你运动平台的直线度。有一次我忽略了平台抖动,标定结果反复横跳,查了两天才找到原因。
2.4 世界坐标系:你的尺子
世界坐标系是你自己定义的。你可以把原点放在标定板的第一个角点,也可以放在机台底座。怎么方便怎么来。
从世界坐标到相机坐标,需要一个刚体变换:
[Xc] [R11 R12 R13] [Xw] [Tx]
[Yc] = [R21 R22 R23] [Yw] + [Ty]
[Zc] [R31 R32 R33] [Zw] [Tz]
R 是 3x3 旋转矩阵,T 是 3x1 平移向量。合起来就是外参,描述相机在世界中的位姿。
这里有个细节:旋转矩阵虽然有 9 个元素,但自由度只有 3(绕 X、Y、Z 轴的旋转角)。所以实际标定时,我们通常用旋转向量或欧拉角来表示,减少参数冗余。
| 坐标系 | 维度 | 单位 | 原点 | 典型值(线扫) |
|---|---|---|---|---|
| 像素坐标系 | 2D | pixel | 图像左上角 | u: 0~8192, v: 0~N |
| 图像坐标系 | 2D | mm | 主点 (cx, cy) | x: ±20mm, y: ±15mm |
| 相机坐标系 | 3D | mm | 光心 | Zc: 100~1000mm |
| 世界坐标系 | 3D | mm | 自定义 | 标定板角点 |
2.5 线扫相机的特殊之处
面阵相机一次拍一张图,线扫相机一次拍一行。所以线扫的成像模型里,多了一个运动维度。
具体来说,线扫相机的像素坐标 v 方向,对应的是运动平台的位移。假设平台移动速度为 V(mm/s),线扫相机的行频为 H(Hz),那么:
v = (t * V) / (dy * H)
其中 t 是曝光时刻。你看,v 坐标直接和运动耦合了。如果平台速度不稳,图像就会拉伸或压缩。
避坑指南:做线扫标定时,一定要先确认运动平台的编码器精度。我建议至少用 1000 线/mm 的光栅尺,否则标定结果会带进运动误差。
2.6 完整的转换链
把上面所有步骤串起来,从世界坐标到像素坐标的完整公式是:
s * [u] [fx s cx] [R11 R12 R13 Tx] [Xw]
[v] = [0 fy cy] [R21 R22 R23 Ty] [Yw]
[1] [0 0 1] [R31 R32 R33 Tz] [Zw]
[0 0 0 1 ] [1 ]
左边 s 是尺度因子,右边第一个矩阵是内参矩阵 K,第二个是外参矩阵 [R|T]。
标定的任务,就是解出 K 和 [R|T] 里的所有未知数。
我的经验:实际标定时,我通常会用 10~15 张不同位姿的标定板图像。太少解不稳定,太多计算量上去了精度提升有限。10~15 张是个甜点区间。
2.7 畸变模型:理想很丰满,现实很骨感
上面讲的都是理想针孔模型。但实际镜头有畸变,尤其是线扫相机常用的柱面镜头,畸变更明显。
常见的畸变有两种:
- 径向畸变:光线通过镜头边缘时弯曲,表现为图像桶形或枕形失真
- 切向畸变:镜头与成像平面不平行,表现为图像倾斜
畸变校正公式(以径向畸变为例):
x_corrected = x * (1 + k1*r^2 + k2*r^4 + k3*r^6)
y_corrected = y * (1 + k1*r^2 + k2*r^4 + k3*r^6)
其中 r^2 = x^2 + y^2,k1、k2、k3 是畸变系数。
注意:线扫相机通常只校正 x 方向的畸变,因为 y 方向是运动合成的。我见过有人把面阵的畸变模型直接套在线扫上,结果越校越歪。千万别这么干。