2、相机成像模型:针孔相机模型、坐标系转换(世界、相机、图像、像素)、相机内参与外参
大家好,我是你们的讲师。今天我们来聊聊立体匹配里最基础、也最绕不开的一个话题——相机成像模型。
说实话,我刚开始做双目视觉那会儿,觉得这东西不就是「拍照嘛,有啥好研究的」。结果第一次标定相机,出来的点云全是扭曲的,我才意识到——不懂成像模型,你连像素和现实世界的对应关系都搞不清楚。
这一节,我会带你彻底搞懂四个坐标系之间的转换,以及相机内参和外参到底在干什么。嗯,咱们从最简单的针孔相机模型开始。
2.1 针孔相机模型:最朴素的成像原理
你想想看,最早的相机其实就是个暗箱。光线从一个小孔射进去,在后面的感光面上形成倒像。这就是针孔相机模型的核心思想。
数学上,我们用一个小孔(光心)和成像平面来模拟这个过程。假设三维空间里有一个点 P,它通过光心投影到成像平面上,得到像点 p。
这里有个关键公式:
X' = f * (X / Z)
Y' = f * (Y / Z)
其中 (X, Y, Z) 是三维点在相机坐标系下的坐标,f 是焦距(光心到成像平面的距离),(X', Y') 是像点在成像平面上的物理坐标。
核心要点:针孔模型是一个线性模型,但实际镜头会有畸变。我在项目中遇到过,直接用针孔模型去算,结果边缘的物体全歪了。所以后面我们还得做畸变校正。
2.2 四个坐标系:从世界到像素的「四步走」
一个三维点怎么变成像素坐标?说白了,要经过四次坐标变换。我习惯把这四个坐标系记成一条流水线:
- 世界坐标系:你站在哪里看世界?这是绝对坐标,单位是米。
- 相机坐标系:以相机光心为原点,Z轴指向镜头前方。单位还是米。
- 图像坐标系:在成像平面上,以光轴与平面的交点为原点,单位是毫米。
- 像素坐标系:图像左上角为原点,单位是像素。
为什么会搞这么复杂?因为每个环节的「度量衡」不一样。世界坐标是米,像素坐标是像素,中间必须有个桥梁。
2.3 坐标系转换:一步步拆解
2.3.1 世界坐标系 → 相机坐标系(外参干的活)
这一步用到的就是相机外参——旋转矩阵 R 和平移向量 t。公式很简单:
P_cam = R * P_world + t
R 是 3x3 的旋转矩阵,t 是 3x1 的平移向量。说白了,就是把世界坐标「搬到」相机坐标系下。
我的经验:外参的物理意义就是「相机在世界中的位姿」。你想想看,如果你把相机转个角度,R 就变了;如果你把相机挪个位置,t 就变了。标定的时候,我们就是在求这两个东西。
2.3.2 相机坐标系 → 图像坐标系(内参的投影)
这一步就是针孔模型的投影。把三维点 (X_c, Y_c, Z_c) 投影到成像平面上:
x = f * (X_c / Z_c)
y = f * (Y_c / Z_c)
这里 (x, y) 是图像坐标系下的物理坐标,单位是毫米。f 是焦距,单位也是毫米。
2.3.3 图像坐标系 → 像素坐标系(离散化)
这一步是把连续的物理坐标变成离散的像素坐标。公式是:
u = x / dx + u0
v = y / dy + v0
其中 dx、dy 是每个像素在 x、y 方向上的物理尺寸(毫米/像素),(u0, v0) 是图像中心(光轴与图像平面的交点)的像素坐标。
注意:dx 和 dy 不一定相等,尤其是 CMOS 传感器像素不是正方形的时候。我曾经因为没注意这个,算出来的深度图比例全错了,排查了半天才发现是像素宽高比的问题。
2.4 相机内参与外参:一张表说清楚
| 参数类型 | 包含内容 | 物理意义 | 维度 |
|---|---|---|---|
| 内参 | f, dx, dy, u0, v0 | 相机本身的几何特性(焦距、像素尺寸、主点位置) | 3x3 矩阵 |
| 外参 | R, t | 相机在世界坐标系中的位姿(旋转+平移) | R: 3x3, t: 3x1 |
内参矩阵 K 通常写成:
K = [ fx 0 u0 ]
[ 0 fy u0 ]
[ 0 0 1 ]
其中 fx = f / dx,fy = f / dy。注意,fx 和 fy 的单位是像素,不是毫米。
一句话总结:内参是「相机自己的事」,外参是「相机在哪、朝哪看的事」。标定就是同时求出这两套参数。
2.5 完整转换公式:从世界到像素
把上面三步合起来,就是完整的投影公式:
Z_c * [u] = K * [R | t] * [X_w]
[v] [Y_w]
[1] [Z_w]
[1]
这个公式你会在所有立体匹配的论文里看到。它把世界坐标 (X_w, Y_w, Z_w) 映射到像素坐标 (u, v),中间经过了外参变换和内参投影。
嗯,这里要注意:Z_c 是相机坐标系下的深度值,它不能直接消掉。因为投影过程中深度信息被「压缩」了,这也是为什么单目相机无法直接恢复深度——你丢失了尺度信息。
2.6 知识体系图:一张 SVG 帮你理清
下面这张图展示了四个坐标系之间的转换关系,以及内参、外参分别在哪个环节起作用。我个人觉得,把这张图记在脑子里,比背公式管用多了。
2.7 避坑指南:我踩过的几个坑
- 坐标系方向搞反:我曾经把相机坐标系的 Z 轴方向搞反了,结果算出来的深度全是负数。记住:相机坐标系 Z 轴指向镜头前方,右手系。
- 像素坐标原点:OpenCV 里像素坐标原点在左上角,u 轴向右,v 轴向下。这和数学里常见的坐标系不一样,容易搞混。
- 内参矩阵的单位:fx、fy 的单位是像素,不是毫米。如果你用毫米去算,结果会差一个数量级。
- 畸变模型:针孔模型是理想情况,实际镜头有径向畸变和切向畸变。标定时一定要做畸变校正,否则立体匹配的精度会大打折扣。
我的建议:刚开始学的时候,别急着背公式。先拿一个标定板,用 OpenCV 的 calibrateCamera 跑一遍,看看内参矩阵长什么样,外参怎么变化。实践出真知,真的。
好了,这一节的内容就到这里。相机成像模型是立体匹配的基石,搞懂了它,后面的极线约束、视差计算才能顺利推进。记住那张 SVG 图,四个坐标系、内参外参,缺一不可。