2、成像模型与坐标系:像素坐标系、图像坐标系、相机坐标系、世界坐标系

做线扫相机标定,绕不开坐标系。说白了,你看到的每一张图像,背后都藏着四个坐标系在来回变换。我刚开始接触这行时,也被这些坐标绕得头晕。后来亲手调过几套线扫系统,才慢慢摸清它们的脾气。

今天咱们就把这四个坐标系彻底捋清楚。你想想看,相机拍到的像素点,怎么变成真实世界里的物理位置?中间经历了什么?这就是本节要讲的核心。

2.1 四个坐标系,一个都不能少

先给个全景图。四个坐标系分别是:

  • 像素坐标系:图像上的行列号,单位是像素 (pixel)
  • 图像坐标系:成像平面上的物理位置,单位是毫米 (mm)
  • 相机坐标系:以相机光心为原点的三维坐标系,单位是毫米 (mm)
  • 世界坐标系:你自定义的全局参考系,单位是毫米 (mm)

它们的关系就像一条流水线:世界坐标 → 相机坐标 → 图像坐标 → 像素坐标。标定的本质,就是求出这条流水线上每一步的转换参数。

核心观点:标定不是目的,建立从像素到世界的映射才是。你标定出来的参数,就是这条映射链上的钥匙。

坐标系转换流水线 世界坐标系 (Xw, Yw, Zw) 外参 相机坐标系 (Xc, Yc, Zc) 内参 图像坐标系 (x, y) 仿射 像素坐标系 (u, v) 关键说明: • 外参:世界→相机,包含旋转 R 和平移 t,描述相机在世界中的位姿 • 内参:相机→图像,包含焦距 f、主点 (cx, cy)、畸变系数等 • 仿射变换:图像→像素,包含像素尺寸 dx、dy 和倾斜因子 s

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 方向是运动合成的。我见过有人把面阵的畸变模型直接套在线扫上,结果越校越歪。千万别这么干。