4. 相机成像模型:从光线到像素的数学之旅

相机是怎么把三维世界变成一张二维照片的?这个问题,我刚入行时也觉得很简单——不就是镜头一按嘛。直到第一次做视觉定位,发现算出来的坐标总是偏的,才老老实实回来啃成像模型。

说白了,相机成像就是四个步骤:世界坐标 → 相机坐标 → 图像坐标 → 像素坐标。每一步都有对应的数学变换,咱们一个一个拆开看。

核心一句话:相机成像模型就是用数学描述「三维空间点 → 二维像素点」的映射关系。搞懂它,你才能知道相机看到的和实际位置之间差了什么。

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

针孔相机模型是所有成像模型的基础。你想想看,一个暗箱,前面戳个小孔,光线穿过小孔在后面的感光面上成像——就这么简单。

数学上,它描述的是相似三角形关系:

设空间点 P(X, Y, Z),成像点 p(x, y),焦距 f
则:
x = f * (X / Z)
y = f * (Y / Z)

这里有个关键点:Z 是深度。没有深度信息,你没法从单张图恢复三维坐标。我在做单目视觉定位时,就因为这个吃了不少苦头。

我的习惯:每次拿到新相机,第一件事就是画针孔模型的示意图,把坐标系标清楚。坐标系一乱,后面全白干。

4.2 内参矩阵:从物理世界到像素的「翻译官」

针孔模型给出的是物理坐标(单位:毫米),但相机输出的是像素坐标(单位:像素)。怎么转换?靠内参矩阵。

内参矩阵 K 长这样:

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

其中:

  • fx, fy:焦距在 x、y 方向的像素当量(单位:像素/毫米)
  • cx, cy:主点偏移,即光轴与感光面交点的像素坐标

完整投影公式:

s * [u, v, 1]^T = K * [R|t] * [X, Y, Z, 1]^T

s 是尺度因子,[R|t] 是外参(相机位姿)。这个公式我背得滚瓜烂熟——有一次标定完发现内参矩阵里的 cx 偏了 20 多个像素,查了半天才发现是镜头装歪了。

参数 含义 典型值范围
fx x 方向焦距(像素) 500 ~ 2000
fy y 方向焦距(像素) 500 ~ 2000
cx 主点 x 坐标 图像宽度的一半附近
cy 主点 y 坐标 图像高度的一半附近
注意:内参矩阵是相机出厂就定死的,但温度、震动、镜头松动都会让它漂移。我建议每半年重新标定一次,尤其是机器人上用的相机。

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

理想针孔模型假设镜头是完美的,但现实中的镜头有各种「毛病」。畸变主要分两类:径向畸变和切向畸变。

4.3.1 径向畸变

径向畸变是镜头形状导致的。光线经过透镜边缘时弯曲程度和中心不一样,结果就是图像边缘的直线变弯了。

  • 桶形畸变:图像向外凸,像桶一样。广角镜头常见。
  • 枕形畸变:图像向内凹,像枕头。长焦镜头常见。

数学模型(泰勒展开):

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 大得离谱,校正后的图像边缘还是歪的。后来加了 k3 项才搞定——高阶项有时候真不能省。

4.3.2 切向畸变

切向畸变是镜头和感光面不平行导致的。说白了就是镜头装歪了,或者感光芯片贴歪了。

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 是切向畸变系数
避坑指南:我曾经在产线上遇到一批相机,切向畸变系数 p1、p2 特别大。一开始以为是算法问题,后来拆开一看——镜头座没拧紧。机械装配的锅,别让算法背。

4.4 相机标定原理:给相机「量体裁衣」

相机标定,说白了就是求内参和畸变系数。怎么求?用已知尺寸的标定板,拍多张不同角度的照片,然后解方程。

最常用的方法是张正友标定法,流程如下:

  1. 准备标定板:棋盘格或圆点阵,尺寸要精确测量
  2. 采集图像:拍 10~20 张不同角度、不同距离的照片
  3. 提取角点:用亚像素精度提取棋盘格角点坐标
  4. 求解内参:基于单应性矩阵,用最小二乘法初估内参
  5. 优化畸变:用非线性优化(如 Levenberg-Marquardt)精调所有参数
  6. 验证结果:重投影误差 < 0.5 像素才算合格
重投影误差:把标定板上的三维点投影到图像上,算投影点和实际检测点之间的距离。这个值越小,标定越准。我一般要求 < 0.3 像素。

下面这张图总结了相机成像的完整流程:

相机成像模型知识结构图 相机成像模型知识结构 世界坐标系 外参 [R|t] 相机坐标系 内参矩阵 K 畸变模型 径向畸变 (k1,k2,k3) 切向畸变 (p1,p2) 相机标定 ① 准备标定板 ② 采集多角度图像 ③ 提取角点 ④ 求解内参初值 ⑤ 非线性优化畸变 ⑥ 验证重投影误差 核心流程:世界坐标 → 外参变换 → 相机坐标 → 内参投影 → 畸变校正 → 像素坐标

4.5 标定实操要点

理论说完了,聊点实战经验。标定这件事,看着简单,坑不少。

常见翻车现场:
  • 标定板不平——打印在纸上贴硬纸板,纸板弯了,标定全废
  • 照片太少或角度单一——只拍正面,畸变参数根本解不出来
  • 标定板尺寸量错——fx、fy 全偏,后续三维重建全歪

我个人的标定流程:

  1. 用玻璃基板的陶瓷棋盘格(热胀冷缩小,精度高)
  2. 拍 15~20 张,覆盖画面四个角和中心,距离从近到远
  3. 每张图的重投影误差单独看,超过 0.5 像素的直接扔掉
  4. 标定完用一张没参与标定的图做验证
小技巧:标定的时候,让标定板在画面中占 1/3 到 1/2 的面积。太小了角点检测不准,太大了容易超出景深范围。

嗯,相机成像模型这部分就这些。搞懂了针孔模型、内参矩阵、畸变模型和标定原理,你就能把相机输出的像素坐标和真实世界的三维坐标对应起来。这是后面做手眼标定和视觉定位的基础,务必吃透。