2. 相机成像模型:针孔相机模型、世界坐标系到像素坐标系的转换、内参与外参矩阵
做立体匹配,第一件事是什么?
不是调算法,不是调参数。是先把相机怎么成像这件事搞明白。
我见过太多同学,上来就怼SGM、怼代价聚合,结果标定矩阵写错了,视差图怎么调都不对。最后发现,是坐标系转换出了问题。嗯,这种坑我踩过不止一次。
2.1 针孔相机模型:最朴素的成像原理
说白了,相机成像就是一个「三维世界 → 二维平面」的投影过程。
针孔模型是最简单的模型。想象一个密闭盒子,前面戳一个小孔,光线穿过小孔,在后面的感光平面上倒立成像。这就是针孔相机。
核心思想: 三维空间中的点P(X, Y, Z),通过光心O,投影到成像平面上的点p(x, y)。
数学关系很简单:x = f * X / Z,y = f * Y / Z。
其中f是焦距,Z是物距。
这里有个细节要注意:实际相机不是针孔,是透镜。透镜会引入畸变。但针孔模型是基础,畸变校正是在这个模型上做的修正。
我个人习惯,在讲立体匹配之前,先让学生手推一遍针孔模型的投影公式。为什么?因为后面所有的坐标系转换、视差计算、三角测量,都建立在这个公式上。
2.2 四个坐标系:从世界到像素
实际工程中,我们不会直接用物理坐标。我们需要在四个坐标系之间来回切换。
哪四个?
- 世界坐标系:你放相机的地方。单位是米或毫米。
- 相机坐标系:以光心为原点,Z轴指向镜头前方。
- 图像坐标系:在成像平面上,单位是毫米。原点在光轴与平面的交点。
- 像素坐标系:最终你看到的图像。单位是像素。原点在左上角。
我的经验: 很多初学者搞混「图像坐标系」和「像素坐标系」。图像坐标系的原点在图像中心,像素坐标系的原点在左上角。两者差一个平移量。我在做双目标定时,就因为这个平移量没算对,导致视差图偏移了十几个像素。排查了一整天。
2.3 世界坐标系 → 相机坐标系:外参矩阵
世界坐标系和相机坐标系之间是什么关系?
说白了,就是刚体变换——旋转加平移。
一个点在世界坐标系下的坐标是Pw = (Xw, Yw, Zw)T,在相机坐标系下是Pc = (Xc, Yc, Zc)T。
转换公式:
Pc = R · Pw + t
其中R是3×3旋转矩阵,t是3×1平移向量。
写成齐次形式:
[Xc] [R t] [Xw]
[Yc] = [ ] [Yw]
[Zc] [0 1] [Zw]
[1 ] [1 ]
这个4×4矩阵,就是外参矩阵。
外参矩阵的意义: 描述相机在世界坐标系中的位置和朝向。
每个相机都有自己的外参。在双目系统中,左右相机的外参不同,它们之间的相对关系就是「双目外参」。
我记得有一次做双目测距,左相机外参标定好了,右相机外参怎么都对不上。后来发现是旋转矩阵的欧拉角顺序搞反了。嗯,这里要注意:旋转矩阵不满足交换律,顺序错了结果完全不一样。
2.4 相机坐标系 → 图像坐标系:内参矩阵
这一步就是针孔模型的投影。
相机坐标系下的点Pc = (Xc, Yc, Zc)T,投影到图像坐标系:
x = f · Xc / Zc
y = f · Yc / Zc
写成矩阵形式:
[x] [f 0 0] [Xc]
[y] = [0 f 0] [Yc]
[1] [0 0 1] [Zc]
但这是理想情况。实际相机还有两个问题:
- 像素不是正方形,x和y方向的焦距可能不同(fx和fy)
- 主点(光轴与成像平面的交点)不一定在像素中心,有偏移(cx, cy)
所以实际的内参矩阵是:
K = [fx 0 cx]
[0 fy cy]
[0 0 1 ]
避坑指南: 我曾经在标定的时候,把fx和fy当成同一个值处理。结果校正后的图像出现了拉伸变形。后来才发现,工业相机的像素尺寸不一定是正方形,fx和fy必须分别标定。
2.5 图像坐标系 → 像素坐标系:离散化
这一步最简单,就是把连续坐标变成离散像素坐标。
假设每个像素的物理尺寸是dx × dy(毫米/像素),那么:
u = x / dx + u0
v = y / dy + v0
其中(u0, v0)是图像坐标系原点在像素坐标系中的位置。
把这一步和上一步合并,就得到完整的内参矩阵:
K = [f/dx 0 u0]
[0 f/dy v0]
[0 0 1 ]
通常记作:
K = [fx 0 cx]
[0 fy cy]
[0 0 1 ]
2.6 完整转换:世界 → 像素
把上面所有步骤串起来:
世界坐标 → 相机坐标 → 图像坐标 → 像素坐标
s · [u] [fx 0 cx] [R t] [Xw]
[v] = [0 fy cy] [ ] [Yw]
[1] [0 0 1 ] [0 1] [Zw]
[1 ]
其中s是尺度因子(其实就是Zc)。
这个公式,就是整个相机成像的核心公式。
一句话总结: 内参K描述相机本身的属性(焦距、主点),外参[R|t]描述相机在世界中的位姿。
标定的目的,就是求K和[R|t]。
2.7 畸变模型:现实世界的修正
针孔模型是理想情况。实际镜头有畸变,主要是两种:
- 径向畸变:光线在透镜边缘弯曲更厉害,产生「桶形」或「枕形」畸变
- 切向畸变:透镜与成像平面不平行
畸变校正公式(以径向畸变为例):
xcorrected = x(1 + k1r² + k2r⁴ + k3r⁶)
ycorrected = y(1 + k1r² + k2r⁴ + k3r⁶)
其中r² = x² + y²,k1、k2、k3是径向畸变系数。
我的建议: 做立体匹配之前,一定要先做畸变校正和立体校正。否则匹配出来的视差图会有系统性误差。我一般用OpenCV的stereoRectify函数,一步到位。
2.8 本章核心知识图谱
你想想看,整个成像过程,其实就是把三维世界里的一个点,通过四次坐标变换,最终映射到二维图像上的一个像素。每一步都有明确的数学表达。
搞懂了这些,后面讲立体校正、视差计算、三角测量,你就知道每一步在做什么了。
嗯,这一章的内容就到这。记住:内参是相机的「身份证」,外参是相机的「GPS坐标」。两者缺一不可。