4. 相机成像模型与内参矩阵

聊到相机外参解算,咱们得先搞清楚相机是怎么看到世界的。说白了,外参描述的是「相机在哪、朝哪看」,而内参描述的是「相机怎么把看到的东西变成像素」。这两个东西是绑在一起的,缺一个都不行。

我刚开始做视觉SLAM的时候,总觉得内参是标定好的固定值,不用太关心。直到有一次在室外跑数据集,发现投影误差怎么都降不下去,折腾了两天才发现是畸变参数没更新——嗯,从那以后我再也不敢小看内参了。

4.1 针孔相机模型

针孔模型是最经典的成像模型。你想想看,一个小孔,光线穿过它,在后面的成像平面上倒立成像。这就是最朴素的相机原理。

数学上,我们把这个过程拆成三步:

  1. 世界坐标系 → 相机坐标系:靠外参矩阵搞定
  2. 相机坐标系 → 图像坐标系:透视投影,把3D点压到2D平面
  3. 图像坐标系 → 像素坐标系:加上缩放和偏移,变成像素坐标

第二步的透视投影,核心公式就一个:

X' = f * X / Z
Y' = f * Y / Z

其中 (X, Y, Z) 是相机坐标系下的3D点,f 是焦距,(X', Y') 是归一化平面上的坐标。注意,这里 Z 不能为0,否则没意义。

关键理解:针孔模型本质上是「相似三角形」关系。3D点离相机越远,在成像平面上的投影越小。这就是透视效应的根源。

4.2 内参矩阵K的定义

内参矩阵K,就是把归一化坐标映射到像素坐标的那个矩阵。它的标准形式是:

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

各参数含义:

参数 含义 单位
fx, fy x、y方向的焦距(以像素为单位) 像素
cx, cy 主点偏移,即光轴与成像平面交点的像素坐标 像素

为什么 fx 和 fy 可能不一样?因为传感器像素不一定是正方形的。我遇到过一些工业相机,fx 和 fy 差了5%以上,如果不分开处理,重建出来的物体会变形。

完整的投影公式写成齐次坐标形式:

p = K * [R|t] * P_w

其中 p 是像素坐标(齐次),P_w 是世界坐标(齐次),[R|t] 是外参矩阵。这个公式贯穿了整个视觉SLAM,建议你背下来。

我的习惯:拿到一个新相机,第一件事就是看它的内参矩阵。fx 和 fy 的比值能告诉我像素是不是正方形,cx 和 cy 偏离图像中心多少能告诉我镜头装配精度。这些信息对后续的标定和重建都很有用。

4.3 畸变模型

现实中的镜头不是完美的针孔。透镜的曲率、装配误差都会导致图像变形。这就是畸变。

畸变主要分两类:

4.3.1 径向畸变

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

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

数学上,径向畸变用多项式来建模:

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^2 = x^2 + y^2,是归一化坐标到光心的距离。k1、k2、k3 是径向畸变系数。一般只用 k1、k2 就够了,k3 只在鱼眼镜头等大畸变场景才用。

我曾经踩过的坑:有一次标定完相机,发现去畸变后的图像边缘有奇怪的波纹。查了半天,原来是 k3 参数设成了非零值,但我的镜头畸变没那么大,过拟合了。建议:普通镜头只用 k1、k2,除非你确定需要 k3。

4.3.2 切向畸变

切向畸变是镜头和成像平面不平行引起的。说白了,就是镜头装歪了。

数学模型:

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)

p1、p2 是切向畸变系数。这个畸变在消费级相机上一般很小,但在工业相机或手机镜头上偶尔会比较明显。

4.4 完整畸变校正流程

实际项目中,畸变校正的步骤是这样的:

  1. 获取原始像素坐标 (u, v)
  2. 反投影到归一化平面:x = (u - cx)/fx, y = (v - cy)/fy
  3. 计算畸变量:用径向和切向畸变公式计算 (x_distorted, y_distorted)
  4. 重新投影到像素坐标:u' = fx * x_distorted + cx, v' = fy * y_distorted + cy
  5. 插值:用双线性插值获取校正后的像素值

注意,第3步和第4步的顺序不能搞反。我见过有人先做径向畸变再做切向畸变,结果图像边缘出现奇怪的扭曲。

一句话总结:内参矩阵K告诉你「像素和物理尺寸的关系」,畸变参数告诉你「镜头不完美的地方」。两者合在一起,才能把相机看到的原始图像还原成符合针孔模型的理想图像。

4.5 本章知识结构

下面这张图把本章的核心概念串起来了,建议你保存下来对照着看:

相机成像模型与内参矩阵 · 知识结构 针孔相机模型 内参矩阵 K 径向畸变 切向畸变 K = [fx, 0, cx; 0, fy, cy; 0, 0, 1] fx, fy: 焦距(像素) cx, cy: 主点偏移 作用:归一化坐标 → 像素坐标 径向畸变模型 x_dist = x * (1 + k1*r² + k2*r⁴ + k3*r⁶) 桶形畸变 / 枕形畸变 参数:k1, k2, k3 切向畸变模型 x_dist = x + (2*p1*x*y + p2*(r²+2x²)) 镜头与成像平面不平行 参数:p1, p2 畸变校正流程:像素 → 归一化 → 去畸变 → 重投影 → 插值

这张图把针孔模型、内参矩阵、径向畸变、切向畸变以及畸变校正流程串在了一起。你可以在上面看到每个模块的输入输出关系。我个人习惯在做标定之前先画一遍这个图,确保思路清晰。