1. 相机成像模型:从光线到像素的奇幻旅程
大家好,欢迎来到《张正友标定法:从原理到OpenCV实现》的第一章。我是你们的老朋友,一个在计算机视觉领域摸爬滚打多年的工程师。今天,咱们不聊那些枯燥的数学公式,先聊聊相机是怎么“看”世界的。
你可能会想,相机不就是按个快门吗?其实,从现实世界的一个点,到你手机屏幕上的一个像素,中间经历了一系列复杂的坐标变换。这个过程,就是我们今天要讲的相机成像模型。说白了,就是搞清楚“世界上的点”是怎么变成“照片上的点”的。
核心一句话:相机成像模型,就是描述三维空间中的点,如何映射到二维图像平面上的数学工具。它是所有后续标定、三维重建工作的基石。
1.1 小孔成像:最朴素的相机原型
咱们先从最古老的相机——小孔成像说起。我记得小时候上物理课,老师用一个带小孔的纸盒,在暗室里就能把外面的景物倒着投影在墙上。当时觉得特别神奇。
小孔成像的原理其实很简单:
- 光线沿直线传播。
- 物体上每一点发出的光线,只有通过小孔的那一束才能到达成像平面。
- 结果就是:一个倒立的、左右颠倒的实像。
这个模型虽然简单,但它抓住了相机成像的本质:透视投影。你想想看,小孔越小,像越清晰,但进光量也越少,像就越暗。这就是一个天然的矛盾。现代相机用透镜来解决这个问题,但透视投影的几何关系,依然是从小孔模型衍生出来的。
我的经验:在早期做视觉定位项目时,我一度觉得小孔模型太简单,不够用。后来发现,只要理解了小孔成像的几何关系,很多复杂的畸变模型、投影模型,都能找到对应的“小孔版本”来理解。它就像一把万能钥匙。
1.2 针孔相机模型:数学化的理想相机
小孔成像太“物理”了,工程师们需要把它变成数学公式。于是就有了针孔相机模型。它是对真实相机的一种理想化抽象,假设相机就是一个完美的针孔。
在这个模型里,有几个关键角色:
- 光心 (Optical Center): 就是那个小孔的位置,记作 \(O\)。
- 光轴 (Optical Axis): 穿过光心,垂直于成像平面的直线。
- 成像平面 (Image Plane): 光线投影后形成图像的地方。
- 焦距 (Focal Length): 光心到成像平面的距离,记作 \(f\)。
为了数学上方便,我们通常把成像平面“虚拟”地放到光心前面(正立虚像平面),这样图像就是正立的了。这个操作在数学上是等价的,但能省去处理倒像的麻烦。
那么,一个三维空间点 \(P(X, Y, Z)\) 是怎么投影到图像点 \(p(x, y)\) 的呢?
根据相似三角形,我们可以得到:
x = f * (X / Z)
y = f * (Y / Z)
看到没?\(Z\) 在分母上。这意味着:物体离相机越远(Z越大),它在图像上的像就越小。这就是“近大远小”的数学本质。
避坑指南:我曾经在做一个AR项目时,直接用了这个公式,结果发现虚拟物体总是对不准真实场景。后来排查了半天,才发现是忽略了单位问题。公式里的 \(f\) 和 \(X, Y, Z\) 必须使用同一套单位(比如毫米)。如果 \(f\) 是像素单位,那 \(X, Y, Z\) 也得是像素单位?不对,\(X, Y, Z\) 是物理世界的米,所以这里需要先做单位转换。这个坑,我替你们踩过了。
1.3 世界坐标系到像素坐标系的转换:四步走
现在,我们有了针孔模型,但问题来了:我们测量物体用的是“世界坐标系”(比如以房间角落为原点),而相机有自己的“相机坐标系”(以光心为原点),图像还有“图像坐标系”(以图像中心为原点),最后才是“像素坐标系”(以图像左上角为原点)。
这四者之间怎么转换?我习惯把它拆成四步,每一步对应一个变换矩阵。你想想看,这就像把货物从工厂(世界)运到仓库(相机),再分拣到货架(图像),最后贴上条形码(像素)。
| 步骤 | 变换名称 | 输入坐标系 | 输出坐标系 | 变换矩阵 | 参数 |
|---|---|---|---|---|---|
| 1 | 刚体变换 | 世界坐标系 | 相机坐标系 | \([R|t]\) | 旋转矩阵 \(R\),平移向量 \(t\) |
| 2 | 透视投影 | 相机坐标系 | 归一化图像坐标系 | \(\begin{bmatrix} f & 0 & 0 \\ 0 & f & 0 \\ 0 & 0 & 1 \end{bmatrix}\) | 焦距 \(f\) |
| 3 | 图像物理坐标 | 归一化图像坐标系 | 图像坐标系 | \(\begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}\) | (单位转换,通常隐含在下一步) |
| 4 | 像素坐标 | 图像坐标系 | 像素坐标系 | \(\begin{bmatrix} 1/dx & 0 & u_0 \\ 0 & 1/dy & v_0 \\ 0 & 0 & 1 \end{bmatrix}\) | 像素尺寸 \(dx, dy\),主点 \((u_0, v_0)\) |
嗯,这里要注意,步骤2和步骤3、4经常被合并成一个内参矩阵 \(K\)。这个 \(K\) 矩阵,就是相机的“身份证”,包含了焦距、主点、像素尺寸等信息。
最终,整个变换可以写成:
s * [u, v, 1]^T = K * [R|t] * [X, Y, Z, 1]^T
其中,\(s\) 是一个尺度因子,\([u, v]\) 是像素坐标,\([X, Y, Z]\) 是世界坐标。这个公式,就是相机成像模型的终极形态。你把它背下来,后面的标定、三维重建,全都要靠它。
1.4 知识体系总览:一张图看懂
说了这么多,咱们用一张SVG图来总结一下整个知识体系。这张图是我自己设计的,把四个坐标系和它们之间的变换关系画得清清楚楚。
这张图里,从左到右,从上到下,清晰地展示了从世界坐标到像素坐标的完整流程。外参 \([R|t]\) 负责把世界坐标“搬”到相机坐标系,内参 \(K\) 负责把相机坐标“投影”到像素坐标。标定的任务,就是求出这两个矩阵。
1.5 小结:你学到了什么?
好了,这一章的内容就到这里。我们从小孔成像的物理原理出发,建立了针孔相机模型的数学框架,然后一步步推导了从世界坐标系到像素坐标系的完整变换过程。最后,我们用一张SVG图把整个知识体系串了起来。
我个人觉得,理解这个模型的关键,不在于记住那个复杂的矩阵公式,而在于理解每一步变换的物理意义。为什么要有外参?因为相机可以放在任何地方。为什么要有内参?因为每个相机的镜头和传感器都不一样。当你把这些问题想明白了,后面的标定算法,就只是水到渠成的事了。
课后小练习:找一张你手机拍的照片,查一下它的EXIF信息,看看能不能找到焦距(Focal Length)和像素尺寸(通常没有直接给出,但可以通过传感器尺寸和分辨率推算)。然后,试着用本章的公式,估算一下照片里某个物体离你的距离。你会发现,理论联系实际,是学习计算机视觉最好的方法。