2. 针孔相机模型:内参矩阵K的推导,焦距、主点偏移的物理意义

说到相机模型,我第一个想到的就是针孔模型。它是最基础、最经典的成像模型。你想想看,一个暗箱,前面戳个小孔,外面的光线穿过小孔,在后面的感光面上形成倒像——就这么简单。但就是从这个简单模型里,我们推导出了整个视觉几何的基石:内参矩阵K。

我在做多相机融合项目时,发现很多同事对K矩阵的理解停留在“公式背下来就行”。结果一遇到畸变大的镜头、或者需要手动标定主点偏移时,就抓瞎了。所以这一节,咱们把K矩阵的来龙去脉彻底捋清楚。

2.1 从物理世界到像素坐标

先理清一条线:三维空间中的一个点,是怎么变成照片上一个像素的?

  1. 世界坐标系 → 相机坐标系(刚体变换,外参干的活)
  2. 相机坐标系 → 成像平面坐标系(透视投影,针孔模型干的活)
  3. 成像平面坐标系 → 像素坐标系(离散化、缩放、平移,内参干的活)

内参矩阵K,管的就是最后两步。说白了,它描述的是“相机内部怎么把光线转换成像素”。

核心观点:K矩阵把相机坐标系下的三维点 (X, Y, Z) 映射到像素坐标 (u, v)。这个映射是透视投影 + 仿射变换的组合。

2.2 针孔模型的几何关系

假设相机坐标系下有一个点 P = (X, Y, Z)。它通过针孔投影到成像平面上。根据相似三角形,成像平面上的坐标 (x, y) 满足:

x = f * X / Z
y = f * Y / Z

这里的 f 是物理焦距,单位是毫米。注意,成像平面在针孔后方,所以像是倒的。但我们在数学上通常把成像平面“翻”到针孔前方,这样公式里就没有负号了。我个人习惯用这种“虚拟成像平面”来推导,省心。

好,现在 (x, y) 还是连续的物理坐标(毫米)。下一步,我们要把它变成离散的像素坐标 (u, v)。

2.3 从毫米到像素:内参矩阵的诞生

这一步涉及两个操作:

  • 缩放:每个像素在感光元件上有物理尺寸,比如 dx 毫米/像素、dy 毫米/像素。
  • 平移:成像平面的原点(光轴与成像平面的交点)通常不在像素坐标系的原点(通常是图像左上角),所以需要加一个偏移量。

写成公式就是:

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

把 x = f * X / Z 和 y = f * Y / Z 代进去:

u = (f / dx) * (X / Z) + cx
v = (f / dy) * (Y / Z) + cy

令 fx = f / dx,fy = f / dy,这就是我们常说的等效焦距,单位是像素。然后写成齐次坐标形式:

Z * [u]   = [fx  0  cx] * [X]
    [v]     [ 0 fy  cy]   [Y]
    [1]     [ 0  0   1]   [Z]

中间那个 3x3 矩阵,就是内参矩阵 K。

我的经验:实际标定时,fx 和 fy 往往不相等。因为感光元件的像素不一定是正方形,或者镜头有轻微的拉伸。别硬把它们设成一样,除非你用的是完美正方形像素的传感器——现实中很少见。

2.4 焦距的物理意义

fx 和 fy 的单位是像素。它们综合了两个物理量:

  • 物理焦距 f:镜头的光学属性,单位毫米。焦距越长,视角越窄,远处物体看起来越大。
  • 像素密度 1/dx、1/dy:感光元件的分辨率,单位像素/毫米。同样的物理焦距,像素密度越大,fx 越大,图像看起来越“放大”。

举个例子:两个相机,物理焦距都是 4mm。一个传感器像素尺寸 2μm,另一个 4μm。前者的 fx = 4 / 0.002 = 2000 像素,后者 fx = 4 / 0.004 = 1000 像素。同样的场景,前者拍出来的图像在像素上更“宽”。

避坑指南:我曾经在融合两个不同分辨率的相机时,直接把它们的 fx 当成“焦距”来比较,结果空间映射一塌糊涂。后来才意识到,fx 是物理焦距和像素尺寸的乘积,不能直接对比。要对比物理焦距,得用 fx * dx 反算回去。

2.5 主点偏移的物理意义

主点 (cx, cy) 是光轴与成像平面的交点。理想情况下,它应该在图像正中心。但实际中,由于镜头安装误差、传感器封装偏移,主点往往不在中心。

主点偏移的影响:

  • 它决定了像素坐标系的“零点”在哪里。
  • 在做像素坐标和相机坐标的互相转换时,主点偏移必须精确补偿。
  • 对于广角镜头或鱼眼镜头,主点偏移的影响更明显。

我记得有一次标定一个工业相机,标定出来的 cx 偏离中心 15 个像素。一开始我以为是标定出错了,反复标了三次,结果都一样。后来拆开相机一看,传感器确实贴歪了。嗯,这就是主点偏移的物理来源。

2.6 内参矩阵的完整形式

有些教材还会在 K 矩阵里加一个扭曲参数 s:

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

s 描述的是像素坐标系的 u 轴和 v 轴不垂直的程度。对于大多数现代相机,s 非常接近 0,可以忽略。但如果你用的是老式 CCD 相机或者扫描式相机,s 可能不可忽略。

总结一下:内参矩阵 K 包含 4 个核心参数(fx, fy, cx, cy),加上可选的 s,总共 5 个内参。它们描述了从相机坐标系到像素坐标系的完整映射。

2.7 知识结构总览

下面这张图把整个推导过程串起来了。我建议你多看几遍,把每个箭头对应的物理意义搞清楚。

内参矩阵K推导流程 相机坐标系下点 (X, Y, Z) 透视投影 成像平面坐标 (x, y) 单位:mm 缩放+平移 像素坐标 (u, v) 单位:pixel 核心公式(齐次坐标形式) Z · [u, v, 1]ᵀ = K · [X, Y, Z]ᵀ K = [[fx, s, cx], [0, fy, cy], [0, 0, 1]] 其中 fx = f/dx, fy = f/dy 内参矩阵参数物理意义 fx, fy:等效焦距(像素),= 物理焦距 / 像素尺寸 cx, cy:主点偏移(像素),光轴与成像平面交点 s:扭曲参数(通常≈0),描述像素轴不垂直度 注:fx 和 fy 不等 → 像素非正方形;cx, cy 偏离中心 → 传感器安装偏移

2.8 内参矩阵在SLAM中的角色

在SLAM系统里,内参矩阵K几乎无处不在:

应用场景 K矩阵的作用
特征点三角化 将像素坐标反投影到归一化平面,再结合深度恢复3D点
重投影误差计算 将3D点投影回像素坐标,与观测到的像素坐标比较
本质矩阵/基础矩阵 需要K矩阵将像素坐标归一化,才能计算本质矩阵
多相机融合 每个相机有自己的K,融合前必须统一到同一个坐标系
畸变校正 校正后的像素坐标需要K矩阵重新映射到原始图像

我的建议:在做异构相机融合时,先把每个相机的K矩阵标定准确。我见过太多项目,花大量时间调融合算法,结果问题出在内参标定上——fx 差了 0.5 个像素,融合出来的点云就错位了。内参是地基,地基不稳,上层建筑再漂亮也没用。

2.9 一个简单的数值例子

假设一个相机:

  • 物理焦距 f = 5 mm
  • 像素尺寸 dx = dy = 0.004 mm/pixel(4μm)
  • 图像分辨率 1920×1080
  • 主点偏移 cx = 960, cy = 540(理想中心)

那么:

fx = 5 / 0.004 = 1250 像素
fy = 5 / 0.004 = 1250 像素
K = [1250   0  960]
    [   0 1250  540]
    [   0    0    1]

现在,相机坐标系下有一个点 P = (0.5m, 0.3m, 2.0m)。它在图像上的像素坐标是:

u = 1250 * 0.5 / 2.0 + 960 = 1272.5
v = 1250 * 0.3 / 2.0 + 540 = 727.5

这个点会出现在图像的第1273列、第728行附近。你看,整个过程就是这么直接。

注意:实际项目中,像素坐标是离散的整数。但计算出来的 u, v 通常是浮点数。在做重投影时,我们一般保留浮点精度,只在最终显示或提取像素值时取整。我曾经因为提前取整,导致三角化出来的3D点精度损失了将近1厘米——教训深刻。