2. 针孔相机模型

相机标定这件事,说白了就是搞清楚「世界上的一个点,到底是怎么变成照片里的一个像素的」。

我刚开始做视觉的时候,觉得拍照嘛,镜头对着就完了。直到有一次做三维重建,发现重建出来的点云全是扭曲的,才意识到——不懂相机模型,你连照片都看不懂。

这一章,我们就从最经典的针孔相机模型讲起。它虽然简单,但几乎所有现代相机模型都是它的变体。

2.1 针孔相机模型:最简单的成像方式

想象一个密闭的盒子,前面戳一个小孔。光线从物体上反射,穿过小孔,在盒子后方的平面上形成一个倒立的像。

这就是针孔相机。它没有镜头,没有畸变,只有一个理想化的几何关系。

核心思想:针孔模型假设所有光线都直线传播,且只通过一个点(光心)。

这个模型里,有几个关键角色:

  • 光心(O):小孔的位置,所有光线的交点。
  • 成像平面:感光元件所在的位置,像落在这里。
  • 焦距(f):光心到成像平面的距离。
  • 主点(principal point):光轴与成像平面的交点。

嗯,这里要注意:真实相机是有镜头的,镜头会引入畸变。但针孔模型是我们理解一切的基础。先把这个搞懂,后面加畸变模型就是水到渠成的事。

2.2 从世界坐标到相机坐标:刚体变换

世界上的一个点,比如墙角那个点,它在世界坐标系里有一个坐标 (X_w, Y_w, Z_w)。

但相机有自己的坐标系——它以光心为原点,光轴为 Z 轴。要把世界点转到相机坐标系,需要做一次刚体变换:旋转 + 平移。

用数学表达就是:

| X_c |   | R11 R12 R13 | | X_w |   | t_x |
| Y_c | = | R21 R22 R23 | | Y_w | + | t_y |
| Z_c |   | R31 R32 R33 | | Z_w |   | t_z |

其中 R 是 3×3 旋转矩阵,t 是 3×1 平移向量。合起来,我们叫它外参(extrinsic parameters)。

我的习惯:外参描述的是「相机在世界中的位置和朝向」。每次标定完,我都会先看一眼外参——如果旋转矩阵的行列式不是 1(或者接近 1),那标定大概率有问题。

2.3 从相机坐标到图像坐标:透视投影

现在点已经在相机坐标系里了,接下来要把它投影到成像平面上。

根据相似三角形,相机坐标系下的点 (X_c, Y_c, Z_c) 在成像平面上的投影位置是:

x = f * X_c / Z_c
y = f * Y_c / Z_c

这里 (x, y) 是图像物理坐标,单位是毫米。注意 Z_c 在分母上——这就是透视效应:离得远的物体看起来小。

我遇到过不少新手,在这里卡住。他们问:「为什么不是 x = f * X_c?」

你想想看,如果真是那样,那一个物体不管远近,在图像上大小都一样——那还怎么判断距离?透视投影正是三维世界在二维平面上成像的本质。

2.4 从图像坐标到像素坐标:内参矩阵

物理坐标 (x, y) 是连续的,但像素是离散的。我们需要把它映射到像素坐标系 (u, v)。

这个映射涉及两个因素:

  • 缩放:每个像素在 x 和 y 方向上的物理尺寸(dx, dy)。
  • 平移:主点 (u0, v0) 在像素坐标系中的位置。

写成矩阵形式:

| u |   | f/dx   0    u0 | | X_c |
| v | = |   0   f/dy  v0 | | Y_c |
| 1 |   |   0    0    1  | | Z_c |

这个 3×3 矩阵就是内参矩阵 K。它包含了焦距、像素尺寸、主点位置——这些都是相机的固有属性。

我曾经踩过的坑:有一次标定完,发现主点坐标偏离图像中心特别远。我以为是标定板没放好,折腾了半天。后来才发现——是相机传感器被装歪了。嗯,硬件问题也会反映在内参里。

2.5 齐次坐标:为什么要引入它?

你注意到没有,上面的投影公式里,Z_c 在分母上。这意味着从三维到二维的映射是非线性的。

非线性在数学上不好处理。尤其是当我们想把外参和内参串起来,写成一个统一的变换时,除法会让我们很头疼。

这时候,齐次坐标就派上用场了。

简单说,齐次坐标就是在普通坐标后面加一个维度:

  • 三维点 (X, Y, Z) → 齐次坐标 (X, Y, Z, 1)
  • 二维点 (u, v) → 齐次坐标 (u, v, 1)

有了齐次坐标,除法就变成了矩阵乘法。透视投影可以写成:

| u |   | f_x   0   u0  0 | | X_w |
| v | = |  0   f_y  v0  0 | | Y_w |
| 1 |   |  0    0    1   0 | | Z_w |
                               |  1  |

等等,这里其实省略了外参。完整的公式是:

s * [u, v, 1]^T = K * [R | t] * [X_w, Y_w, Z_w, 1]^T

s 是一个缩放因子,它让等式两边齐次坐标的最后一个分量相等。

一句话总结:齐次坐标把「除法」变成了「乘法」,把「非线性」变成了「线性」。这是计算机视觉里最优雅的数学技巧之一。

2.6 完整映射流程

把上面所有步骤串起来,从世界点到像素点的完整流程是:

  1. 世界坐标 (X_w, Y_w, Z_w) → 通过外参 (R, t) → 相机坐标 (X_c, Y_c, Z_c)
  2. 相机坐标 (X_c, Y_c, Z_c) → 通过透视投影 → 图像物理坐标 (x, y)
  3. 图像物理坐标 (x, y) → 通过内参 (f_x, f_y, u0, v0) → 像素坐标 (u, v)

用齐次坐标,这三步可以合并成一个矩阵乘法:

s * [u, v, 1]^T = K * [R | t] * [X_w, Y_w, Z_w, 1]^T

这个公式,就是针孔相机模型的完整数学表达。你会在后面每一章里反复见到它。

下面这张图,把整个流程画了出来:

针孔相机模型:从世界坐标到像素坐标 世界坐标 (X_w, Y_w, Z_w) 外参 [R|t] 相机坐标 (X_c, Y_c, Z_c) 透视投影 图像物理坐标 (x, y) 内参 K 像素坐标 (u, v) 关键说明 • 外参 [R|t]:描述相机在世界中的位置和朝向,共 6 个自由度(3 旋转 + 3 平移) • 内参 K:描述相机内部几何特性,包括焦距、主点、像素尺寸,共 4 个自由度(f_x, f_y, u0, v0) • 齐次坐标:将除法变为乘法,使整个映射成为线性变换,便于计算和优化

2.7 内参与外参:一张表说清楚

参数类型 符号 含义 自由度 是否随相机移动变化
内参 f_x, f_y, u0, v0 焦距(像素单位)、主点位置 4 否(固定)
外参 R, t 旋转矩阵、平移向量 6 是(随相机位姿变化)

我的建议:标定的时候,内参只需要标一次。但外参每次移动相机都要重新算。所以如果你把相机固定在一个地方,内参标好了就别动它,只更新外参就行。

2.8 本章小结

针孔相机模型,是整个相机标定的基石。它告诉我们:

  • 一个三维点,经过外参变换、透视投影、内参映射,最终变成一个像素。
  • 齐次坐标让这个非线性过程变成了优雅的线性矩阵乘法。
  • 内参是相机的固有属性,外参描述相机的位置和朝向。