第4章:相机成像模型
相机是怎么把三维世界变成二维图像的?
这个问题,我刚入行时也琢磨了很久。后来做标定项目多了,才真正理解——相机成像模型就是连接三维点和二维像素的那座桥。今天咱们就把这座桥拆开,一块砖一块砖地看。
4.1 针孔相机模型
先说说最简单的模型——针孔相机模型。说白了,就是一个小孔成像。
想象一个密闭的盒子,前面戳个小孔,光线穿过小孔,在后面的感光面上成像。这就是最原始的相机。
数学上怎么描述?
核心公式:
X_cam = [X, Y, Z]^T // 三维点在相机坐标系下的坐标
x = f * X / Z // 归一化到成像平面
y = f * Y / Z
这里有个关键点:Z 不能为 0。你想想看,如果物体正好在相机光心位置,那成像就跑到无穷远去了。实际中当然不会发生,但数学上要留意。
我个人习惯把针孔模型拆成两步理解:
- 投影变换:把三维点映射到归一化平面(Z=1 的平面)
- 缩放平移:把归一化坐标映射到像素坐标
这样做的好处是——畸变校正、立体匹配这些操作,都在归一化平面上做,干净利落。
我的经验:做标定时,我习惯先把所有特征点反投影到归一化平面,再去做优化。这样内参和外参的耦合度最低,收敛也更快。
4.2 畸变模型
现实中的镜头不是完美的针孔。镜头有曲率,有装配误差,这就带来了畸变。
畸变主要分两类:径向畸变和切向畸变。我一个个说。
4.2.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 是径向畸变系数。
注意:k3 一般只在鱼眼镜头或畸变特别大的镜头中使用。普通镜头用 k1、k2 就够了。我曾经在一个项目中盲目加了 k3,结果过拟合,标定结果反而更差。
4.2.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 是切向畸变系数。这个模型是 Brown 在 1971 年提出的,到现在还在用。
我记得有一次做车载相机标定,发现图像边缘的直线总是弯的。一开始以为是径向畸变没校正好,调了半天 k1、k2 都没用。后来一查,原来是镜头装配时有个微小的倾斜。加上 p1、p2 后,问题立刻解决了。
避坑指南:我曾经在标定一个工业相机时,发现重投影误差总是降不下去。排查了很久,最后发现是畸变模型选错了——那个镜头是鱼眼镜头,用普通针孔模型加畸变根本不够。后来换成鱼眼模型,误差直接降了一个数量级。
4.3 内参矩阵
内参矩阵,就是把归一化坐标映射到像素坐标的那个矩阵。它长这样:
K = [fx, 0, cx;
0, fy, cy;
0, 0, 1]
各参数含义:
- fx, fy:焦距在 x、y 方向上的像素长度。单位是像素。
- cx, cy:主点坐标,也就是光轴与成像平面的交点。单位是像素。
为什么 fx 和 fy 可能不一样?因为像素不一定是正方形的。有些相机的像素是矩形,所以 x 和 y 方向的焦距会不同。
完整的成像过程可以写成:
[u] [fx, 0, cx] [X/Z]
[v] = [ 0, fy, cy] * [Y/Z]
[1] [ 0, 0, 1] [ 1 ]
你想想看,这个矩阵其实做了两件事:
- 把归一化坐标 (X/Z, Y/Z) 缩放(乘以 fx、fy)
- 平移(加上 cx、cy)
说白了,就是把物理世界中的角度,映射到图像上的像素位置。
重要:内参矩阵是相机本身的属性,不随相机运动而改变。所以标定一次,只要焦距不变、镜头不换,就可以一直用。
4.4 完整成像流程
把上面所有内容串起来,一个三维点是怎么变成像素的?
- 世界坐标系 → 相机坐标系:通过外参(旋转 R、平移 t)
- 相机坐标系 → 归一化平面:除以 Z,得到 (x, y)
- 归一化坐标 → 畸变坐标:应用径向畸变和切向畸变
- 畸变坐标 → 像素坐标:通过内参矩阵 K
这个流程,我建议你背下来。做标定、做三维重建、做 SLAM,天天都要用。
我的习惯:写代码时,我会把畸变校正和内参映射分开写。这样调试时,可以单独看畸变校正的效果,也可以单独看内参映射的效果。耦合度低,排查问题快。
4.5 知识体系图
下面这张图,把本章的核心逻辑串起来了。建议你多看几遍,理解每个模块之间的关系。
4.6 小结
这一章我们聊了:
- 针孔相机模型:三维点到归一化平面的投影
- 畸变模型:径向畸变(k1, k2, k3)和切向畸变(p1, p2)
- 内参矩阵:归一化坐标到像素坐标的映射
这些是相机标定的基础。你想想看,标定说白了就是求解这些参数——内参、畸变系数、外参。理解了成像模型,标定就成功了一半。
下一章,我们会把这些知识用到实际标定中。到时候,我会带你手写一个标定程序,从图像采集到参数求解,一步步走通。