2. 相机成像模型:从世界到像素的“四步走”

做多相机标定,首先得搞明白一件事:相机到底是怎么“看”世界的?

说白了,相机成像就是把三维空间里的一个点,映射到二维照片上的一个像素。这个过程涉及四个坐标系,我习惯叫它“四步走”。你把这四步吃透了,后面联合标定的矩阵推导才能顺下来。

核心一句话:世界坐标系 → 相机坐标系 → 图像坐标系 → 像素坐标系。每一步都是一个变换。

相机成像四坐标系转换流程 世界坐标系 (Xw, Yw, Zw) 刚体变换 相机坐标系 (Xc, Yc, Zc) 透视投影 图像坐标系 (x, y) 仿射变换 像素坐标系 (u, v) 注意:从世界到相机是外参(R,t),从相机到像素是内参(fx, fy, cx, cy) 联合标定的核心,就是同时求解多个相机的内外参数

2.1 世界坐标系:给物体一个“户口”

世界坐标系就是三维空间的参考系。你放一个标定板在地上,板子角点的坐标就是在这个坐标系下定义的。我一般把世界坐标系的原点放在标定板的第一个内角点上,Z轴垂直于板面。

为什么这么做?因为标定板的尺寸是已知的,角点之间的物理距离是精确的。有了这些已知点,我们才能反推相机的参数。

我的习惯:用棋盘格标定板时,把世界坐标系原点设在棋盘格左上角,X轴向右,Y轴向下,Z轴垂直纸面向里。这样所有角点的Z坐标都是0,计算起来省事不少。

2.2 相机坐标系:以相机为中心看世界

相机坐标系的原点在相机的光心,Z轴指向相机的前方(也就是镜头朝向的方向),X轴向右,Y轴向下。

从世界坐标系到相机坐标系,是一个刚体变换——说白了就是旋转加平移。用数学表达就是:

|Xc|   |R11 R12 R13| |Xw|   |tx|
|Yc| = |R21 R22 R23| |Yw| + |ty|
|Zc|   |R31 R32 R33| |Zw|   |tz|

这里的R是3x3旋转矩阵,t是3x1平移向量。它们合起来就是相机的外参。外参决定了相机在世界中的位置和朝向。

我曾经踩过的坑:旋转矩阵必须是正交矩阵,行列式为+1。有一次我用数值优化算出来的R行列式是0.98,结果投影全偏了。后来加了正交约束才搞定。所以,如果你自己写标定代码,记得检查R的正交性。

2.3 图像坐标系:从三维到二维的“降维打击”

这一步是针孔相机模型的核心。相机坐标系下的点(Xc, Yc, Zc),通过透视投影映射到成像平面上:

x = f * Xc / Zc
y = f * Yc / Zc

其中f是焦距。注意,这里的(x, y)是图像坐标系下的坐标,单位是毫米,原点在成像平面的中心(也就是光轴与成像平面的交点)。

你想想看,这个公式其实就是一个相似三角形。Zc越大,物体在图像上越小——这就是近大远小的原理。

坐标系 维度 单位 原点位置
世界坐标系 3D 毫米/米 自定义(通常标定板角点)
相机坐标系 3D 毫米/米 相机光心
图像坐标系 2D 毫米 成像平面中心
像素坐标系 2D 像素 图像左上角

2.4 像素坐标系:最终的数字图像

图像坐标系是连续的物理坐标,但相机最终输出的是离散的像素。从图像坐标(x, y)到像素坐标(u, v),需要一个仿射变换:

u = x / dx + cx
v = y / dy + cy

其中dx和dy是每个像素在x和y方向上的物理尺寸(单位:毫米/像素),(cx, cy)是主点坐标(单位:像素)。

把前面几步合起来,就是完整的针孔相机模型:

|u|   |fx  0  cx| |R11 R12 R13 tx| |Xw|
|v| = | 0 fy cy| |R21 R22 R23 ty| |Yw|
|1|   | 0  0  1| |R31 R32 R33 tz| |Zw|
                                    | 1|

这里fx = f/dx,fy = f/dy,是归一化焦距。中间的3x4矩阵是外参矩阵,左边的3x3矩阵是内参矩阵。

关键点:内参矩阵只跟相机本身的物理特性有关(焦距、像素尺寸、主点位置),外参矩阵描述相机在世界中的位姿。联合标定多个相机,本质上就是让所有相机共享同一个世界坐标系,然后分别求解各自的外参。

2.5 畸变模型:现实总是不完美的

针孔模型是理想情况。实际镜头会有畸变,主要是径向畸变和切向畸变。

径向畸变:光线通过镜头边缘时弯曲得更厉害,导致图像边缘的直线变弯。用三个参数(k1, k2, k3)来描述:

x_distorted = x * (1 + k1*r^2 + k2*r^4 + k3*r^6)
y_distorted = y * (1 + k1*r^2 + k2*r^4 + k3*r^6)

其中r是点到光心的距离。

切向畸变:镜头和成像平面不平行导致的。用两个参数(p1, p2)来描述:

x_distorted = x + [2*p1*x*y + p2*(r^2 + 2*x^2)]
y_distorted = y + [p1*(r^2 + 2*y^2) + 2*p2*x*y]

我的经验:对于大多数工业镜头,径向畸变占主导,切向畸变通常很小。标定时我一般先只标k1, k2,如果重投影误差还大,再加k3和切向参数。参数越多越容易过拟合,这个度要把握好。

2.6 本章小结:一张表说清楚

步骤 变换类型 输入 输出 参数
世界→相机 刚体变换 (Xw, Yw, Zw) (Xc, Yc, Zc) R, t(外参)
相机→图像 透视投影 (Xc, Yc, Zc) (x, y) f(焦距)
图像→像素 仿射变换 (x, y) (u, v) fx, fy, cx, cy(内参)
理想→实际 畸变校正 (x, y) (x_dist, y_dist) k1, k2, k3, p1, p2