坐标系与投影基础:从像素到世界的桥梁
做BEV感知,说白了就是搞清楚一件事:图像上的一个点,到底对应真实世界中的哪个位置?
反过来也一样——世界中的一个物体,落在图像上会是哪个像素?
这背后就是坐标系和投影变换。我刚开始接触这个领域时,觉得不就是几个矩阵相乘嘛,没什么难的。直到第一次做实车标定,发现投影出来的点全飘了……嗯,从那以后我再也不敢小看这部分内容了。
1. 三个核心坐标系
先搞清楚我们手里有哪些坐标系。一共三个,缺一不可。
1.1 世界坐标系 (World Coordinate System)
这是真实世界的绝对坐标系。你可以把它想象成整个场景的"大地基准"。
- 通常用 (Xw, Yw, Zw) 表示
- 原点可以任意设定,比如道路中心、车辆后轴中心
- 在BEV任务中,世界坐标系通常就是自车坐标系
1.2 相机坐标系 (Camera Coordinate System)
以相机光心为原点,Z轴指向相机前方(沿着光轴方向),X轴向右,Y轴向下(注意,这里和世界坐标系不同)。
为什么Y轴向下?因为图像坐标系的原点在左上角,Y轴向下为正。为了统一,相机坐标系也这么约定。
1.3 像素坐标系 (Pixel Coordinate System)
这个最简单。就是图像上每个像素的位置。
- 原点在图像左上角
- u轴向右,v轴向下
- 单位是像素 (pixel)
注意,像素坐标系和图像物理坐标系(以毫米为单位)之间还有一个缩放关系。这个后面会讲。
2. 坐标系之间的投影变换
现在,我们要把世界坐标系中的一个点,一步步投影到像素坐标系上。整个过程分三步走。
2.1 世界坐标系 → 相机坐标系(外参变换)
这一步用到的就是相机的外参矩阵。说白了,就是描述相机在世界坐标系中的位置和朝向。
变换公式:
X_c = R * X_w + T
其中:
- R 是旋转矩阵 (3x3)
- T 是平移向量 (3x1)
- Xw 是世界坐标
- Xc 是相机坐标
实际工程中,我们通常用齐次坐标来写:
[X_c] [R T] [X_w]
[Y_c] = [0 1] * [Y_w]
[Z_c] [Z_w]
[1 ] [1 ]
2.2 相机坐标系 → 图像物理坐标系(内参投影)
这一步是真正的"投影"。把三维的相机坐标,投影到二维的图像平面上。
公式很简单,就是小孔成像模型:
x = f * X_c / Z_c
y = f * Y_c / Z_c
其中:
- f 是焦距(单位:毫米)
- (x, y) 是图像物理坐标(单位:毫米)
写成矩阵形式:
[x] [f 0 0 0] [X_c]
[y] = [0 f 0 0] * [Y_c]
[1] [0 0 1 0] [Z_c]
[1 ]
2.3 图像物理坐标系 → 像素坐标系(离散化)
这一步把连续的物理坐标,变成离散的像素坐标。
公式:
u = x / dx + u0
v = y / dy + v0
其中:
- dx, dy 是每个像素的物理尺寸(单位:毫米/像素)
- (u0, v0) 是图像中心点的像素坐标
合并成内参矩阵 K:
K = [fx 0 u0]
[0 fy v0]
[0 0 1]
其中 fx = f/dx, fy = f/dy。
3. 完整的投影公式
把上面三步合并,就得到了从世界坐标到像素坐标的完整变换:
Z_c * [u] = K * [R T] * [X_w]
[v] [Y_w]
[1] [Z_w]
[1 ]
这个公式,就是BEV感知中所有几何变换的基石。你想想看,无论是做IPM(逆透视变换),还是做LSS(Lift-Splat-Shoot),本质上都是在求解这个公式的逆过程。
4. 工程中的注意事项
理论讲完了,说点实际的。我在嵌入式平台上部署BEV模型时,遇到过几个坑:
- 浮点数精度问题:嵌入式平台的FPU可能只支持单精度。投影变换中涉及大量除法,精度损失会导致投影偏差。我的做法是:能预先计算的,绝不实时算。比如外参矩阵,标定完就固化,不要每次推理都重新算。
- 畸变校正:实际相机都有畸变(径向畸变、切向畸变)。不做畸变校正,投影出来的点会偏移好几个像素。在BEV任务中,这个误差会被放大。
- 坐标系对齐:多相机系统,每个相机都有自己的外参。必须统一到同一个世界坐标系下。我见过有人把左相机和右相机的外参搞混了,结果BEV图上出现"鬼影"。
5. 总结
坐标系和投影变换,是BEV感知的数学基础。说白了,就是回答两个问题:
- 图像上的像素,对应世界中的哪个点?
- 世界中的物体,落在图像的哪个像素?
搞清楚了这两个问题,后面的BEV特征提取、视角转换,才能有据可依。否则,模型再花哨,投影错了也是白搭。
下一章,我们会讲BEV感知的核心——视角转换。到时候你会发现,所有的视角转换方法,本质上都是在做我们今天讲的这个投影变换的逆过程。