相机成像模型:从世界到像素的“降维打击”

做结构光系统标定,第一个绕不开的坎儿就是相机成像模型。说白了,就是搞明白三维世界里的一个点,是怎么变成照片上那个像素的。这个过程,本质上是个“降维打击”——从三维到二维,信息丢了,但规律还在。

我个人习惯把相机成像拆成四步走:世界坐标系 → 相机坐标系 → 图像坐标系 → 像素坐标系。每一步都有对应的数学变换,也就是我们常说的外参、内参、畸变参数。今天咱们就把这四步掰开揉碎了讲清楚。

核心一句话:相机成像模型 = 刚体变换(外参)+ 透视投影(内参)+ 畸变补偿(非线性)

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

先说说这四个坐标系是干嘛的。你想想看,一个物体在真实世界里,它的位置是用“世界坐标系”描述的。但相机看到的世界,是以它自己为中心的,这就引出了“相机坐标系”。然后光线打到传感器上,形成的是“图像坐标系”(物理单位,比如毫米)。最后,我们读到的图片是像素组成的,所以还得转到“像素坐标系”(单位是像素)。

嗯,这里要注意:初学者最容易搞混的就是图像坐标系和像素坐标系。图像坐标系的原点在光轴与成像平面的交点,单位是毫米;像素坐标系的原点在图像左上角,单位是像素。两者之间差了一个平移和缩放。

我在项目中遇到过有人直接把像素坐标当物理坐标用,结果标定出来的参数全是错的,折腾了两天才发现是坐标系没对齐。所以,坐标系转换的每一步,都要心里有数。

2.2 针孔相机模型:最朴素的成像原理

针孔相机模型,是所有相机模型的基础。它假设光线通过一个小孔(光心)后,在后面的成像平面上形成倒立的像。虽然现在的镜头复杂得多,但数学上我们仍然用这个模型来近似。

从相机坐标系到图像坐标系,就是透视投影:

X_image = f * X_cam / Z_cam
Y_image = f * Y_cam / Z_cam

其中 f 是焦距,单位是毫米。这里有个关键点:Z_cam 是深度信息,投影之后深度就丢了。所以单张图片无法恢复深度,这也是为什么结构光系统需要主动投射图案来“找回”深度。

我的小技巧:实际标定时,我习惯先把所有角点坐标转到归一化平面(Z=1),再乘内参矩阵。这样逻辑更清晰,调试也方便。

2.3 内参矩阵:相机的“身份证”

内参矩阵描述的是相机内部的几何特性。它把归一化平面上的点(x, y, 1)映射到像素坐标(u, v, 1)。标准形式是:

[ fx  0  cx ]
[ 0  fy  cy ]
[ 0   0   1 ]

其中 fx, fy 是焦距在像素单位下的值,cx, cy 是主点坐标(光轴与成像平面的交点)。

为什么 fx 和 fy 可能不一样?因为传感器像素可能不是正方形的。我在标定工业相机时遇到过这种情况,尤其是老旧型号的相机,fx 和 fy 能差好几个像素。如果不单独标定,重建出来的点云会有拉伸变形。

避坑指南:我曾经在标定一个广角镜头时,发现内参矩阵的主点 (cx, cy) 偏离图像中心很多。一开始以为是标定板没放正,后来才发现是镜头装配有偏差。所以,不要假设主点就在图像中心,一定要通过标定来确定。

2.4 外参矩阵:相机在哪儿,朝哪儿看

外参矩阵描述的是世界坐标系和相机坐标系之间的刚体变换。它由一个旋转矩阵 R(3x3)和一个平移向量 t(3x1)组成:

[ R  t ]
[ 0  1 ]

这个矩阵把世界坐标系下的点变换到相机坐标系下。旋转矩阵 R 是正交矩阵,有 3 个自由度(欧拉角或四元数),平移向量 t 有 3 个自由度,所以外参一共 6 个自由度。

实际标定时,外参会随着标定板的摆放位置变化。每次移动标定板,外参都不同,但内参是固定的。这也是张正友标定法的核心思想:利用多张不同位姿的图片,联合优化内参和外参。

2.5 畸变模型:镜头不是完美的

现实中的镜头不是完美的针孔,会有畸变。主要分两类:径向畸变和切向畸变。

径向畸变

径向畸变是光线通过镜头时,边缘弯曲造成的。分为桶形畸变(负畸变)和枕形畸变(正畸变)。数学模型用泰勒级数展开:

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 是径向畸变系数。对于普通镜头,k1 和 k2 就够了;鱼眼镜头可能需要 k3。

我记得有一次标定一个廉价USB摄像头,k1 的值大得离谱,矫正后的图像边缘还是弯的。后来加了 k3 才搞定。所以,如果标定结果不理想,试试增加畸变阶数。

切向畸变

切向畸变是镜头和传感器不平行造成的,比如装配时镜头歪了。模型是:

x_corrected = x + [2*p1*x*y + p2*(r^2 + 2*x^2)]
y_corrected = y + [p1*(r^2 + 2*y^2) + 2*p2*x*y]

p1, p2 是切向畸变系数。实际项目中,切向畸变通常比径向畸变小一个数量级。但如果你做高精度测量,比如结构光三维重建,切向畸变也不能忽略。

经验之谈:标定畸变时,标定板要覆盖整个视场,尤其是边缘。我见过有人只把标定板放在画面中央,结果畸变参数全标成0了。边缘的畸变信息才是关键。

2.6 完整成像流程:从世界到像素

把上面所有步骤串起来,一个世界坐标系下的点 P_w 到像素坐标 p 的完整流程是:

  1. 世界 → 相机:P_c = R * P_w + t
  2. 相机 → 归一化平面:p_n = (X_c/Z_c, Y_c/Z_c, 1)
  3. 畸变矫正:p_n_corrected = distort(p_n, k1, k2, k3, p1, p2)
  4. 归一化平面 → 像素:p = K * p_n_corrected

其中 K 是内参矩阵。这个流程在标定和重建中都会用到。标定时,我们已知像素坐标和世界坐标,反推内参和外参;重建时,我们已知内参和像素坐标,结合结构光提供的深度信息,反推世界坐标。

2.7 本章知识体系图

下面这张图总结了相机成像模型的核心逻辑,从世界坐标系到像素坐标系的完整链路,以及内参、外参、畸变参数各自的位置。

相机成像模型:坐标系与参数链路 世界坐标系 (Xw, Yw, Zw) 外参 R, t 相机坐标系 (Xc, Yc, Zc) 透视投影 图像坐标系 (x, y) 单位mm 内参 K 像素坐标系 (u, v) 单位pixel 畸变模型(非线性) 径向畸变: k1, k2, k3 切向畸变: p1, p2 畸变矫正 标定需要求解的参数 内参 (5个): fx, fy, cx, cy, 畸变系数 (k1, k2, p1, p2, k3) 外参 (6个/每张图): 旋转 R (3个角度) + 平移 t (3个分量) 总自由度: 5 + 6*N (N为标定图片数量),通过最小化重投影误差求解 图:相机成像模型完整链路与标定参数

2.8 小结

相机成像模型是结构光系统标定的基石。四个坐标系、内参外参、畸变模型,这些概念必须烂熟于心。我个人建议,刚开始接触时,不要急着写代码,先手动画一遍从世界坐标到像素坐标的流程,把每一步的矩阵乘法写出来。这样,后面看标定算法的代码时,才能一眼看出它在干什么。

嗯,这一章的内容就到这里。记住,成像模型不是死记硬背的公式,而是你理解相机行为的“思维模型”。搞懂了它,标定和重建的后续内容,就都是水到渠成的事了。


公众号:蓝海资料掘金营,微信deep3321