2、相机成像模型:针孔相机模型、内参矩阵、外参矩阵、畸变模型(径向与切向)

聊到三维重建,绕不开的第一个核心问题就是:相机是怎么看到世界的?

说白了,我们得搞清楚一个三维空间里的点,是怎么跑到二维照片上去的。这个过程,就是相机成像模型要讲的事。我个人习惯把这件事拆成四块来理解:针孔模型、内参、外参、畸变。咱们一个一个来。

2.1 针孔相机模型——最朴素的成像原理

你想想看,最早的相机其实就是个黑盒子,前面戳个小孔。光线从小孔穿进去,在后面的底片上投出一个倒像。这就是针孔模型的核心思想。

数学上怎么描述?很简单。假设世界有个点 P,坐标为 (X, Y, Z)。它通过小孔后,在成像平面上的位置 (x, y) 满足:

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

这里的 f 就是焦距,也就是小孔到成像平面的距离。注意,这个模型假设光线是直线传播的,没有透镜,没有畸变。嗯,现实中当然没有这么完美的事,但它是所有复杂模型的起点。

核心要点:针孔模型本质上是「相似三角形」的比例关系。Z 越大,成像越小;f 越大,成像越大。

我在项目中遇到过一个问题:用手机拍一个棋盘格标定板,明明距离没变,但换了个手机拍出来格子大小差很多。其实就是焦距 f 不一样。所以,焦距是相机最基础的属性

2.2 内参矩阵——从物理坐标到像素坐标

刚才的公式算出来的是物理坐标(单位是毫米),但照片是由像素组成的。怎么把毫米映射到像素?这就需要内参矩阵了。

内参矩阵 K 长这样:

K = | fx   0   cx |
    |  0  fy   cy |
    |  0   0    1 |

其中:

  • fx, fy:分别是 x 和 y 方向上的焦距(单位是像素)。为什么有两个?因为像素不一定是正方形,有些 CMOS 的像素是矩形的。
  • cx, cy:主点坐标,也就是光轴穿过成像平面的那个点。理想情况下在图像正中心,但实际会有偏移。

把针孔模型和内参结合起来,完整的投影公式就是:

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

这里 (u, v) 就是像素坐标了。注意,这个公式里我隐去了归一化平面那一步,实际计算时要把 (X, Y, Z) 先除以 Z 变成归一化坐标。

我的经验:标定内参时,一定要多拍几张不同角度的棋盘格照片。我见过有人只拍 5 张就急着用,结果畸变校正完图像边缘全是扭曲的。至少 15-20 张,覆盖各个角落。

2.3 外参矩阵——相机在哪儿?在看哪儿?

内参解决了「像素怎么算」的问题,但还有个前提:世界坐标系下的点 (X, Y, Z) 是怎么转到相机坐标系下的?

这就靠外参矩阵了。外参描述的是相机在世界坐标系中的位置和朝向。它由一个旋转矩阵 R 和一个平移向量 t 组成:

| X_cam |   | R   t |   | X_world |
| Y_cam | = |       | * | Y_world |
| Z_cam |   | 0   1 |   | Z_world |
|   1   |                 |    1    |

说白了,外参就是把世界坐标「搬」到相机坐标系下。R 负责旋转,t 负责平移。

举个例子:你站在地上拍一个雕塑。雕塑的位置是固定的(世界坐标),你拿着相机转了个角度(R),还往前走了一步(t)。那么雕塑在相机坐标系下的位置就变了。

注意:外参矩阵是 4x4 的齐次矩阵。很多初学者会忘记把三维点补成齐次坐标(加一个 1),导致矩阵乘法报错。我曾经在这个坑里卡了半小时。

2.4 畸变模型——镜头不是完美的

现实中的镜头有透镜,透镜会引入畸变。主要分两种:

2.4.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 是像素到主点的距离,k1、k2、k3 是径向畸变系数。一般 k1 和 k2 就够用了,k3 只在畸变特别大的镜头(比如鱼眼)才需要。

2.4.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 是切向畸变系数。这个畸变在廉价摄像头或者组装工艺差的设备上特别明显。

避坑指南:我曾经用一款工业相机做三维重建,标定完发现重投影误差总是降不下去。折腾了两天,最后发现是镜头没拧紧,轻微晃动导致了切向畸变。拧紧后重新标定,误差直接降了一半。

2.5 知识体系总览

下面这张图把整个相机成像模型的逻辑串起来了。从世界坐标到像素坐标,每一步都有对应的矩阵或模型在起作用。

相机成像模型知识体系 世界坐标 (X_w, Y_w, Z_w) 外参矩阵 [R | t] 相机坐标 (X_c, Y_c, Z_c) 针孔投影 x = f*X/Z 畸变模型 径向 + 切向 内参矩阵 K = [fx, fy, cx, cy] 像素坐标 (u, v) 世界→相机 旋转+平移 归一化 透视投影 畸变校正 像素映射

从这张图可以看得很清楚:世界坐标 → 外参 → 相机坐标 → 针孔投影 → 畸变 → 内参 → 像素坐标。每一步都是上一步的输出作为输入,环环相扣。

实用建议:在实际做三维重建时,我建议你先用 OpenCV 的 calibrateCamera() 跑一遍标定,拿到内参和畸变系数。然后手动验证一下:随便选一个世界坐标点,按上面的流程算一遍像素坐标,看看和实际拍摄的位置是否吻合。这个验证过程能帮你彻底理解整个模型。

好了,相机成像模型就讲到这里。记住,内参是相机的「身份证」,外参是相机的「位置报告」,畸变是镜头的「性格缺陷」。搞懂这三样,你就掌握了三维重建的第一把钥匙。


专注资料整理