第1章:多视图几何基础

大家好,我是你们的自动驾驶感知讲师。今天咱们聊聊多视图几何——说白了,就是怎么让车看懂不同摄像头拍到的同一场景。你想想看,一辆车上装了6个甚至更多摄像头,每个摄像头看到的画面都不一样,怎么把这些信息统一起来?这就是多视图几何要解决的问题。

我个人习惯把多视图几何比作「视觉世界的坐标系转换器」。它帮我们搞清楚:同一个物体在不同相机画面里是什么关系,以及怎么从2D图像反推3D位置。嗯,这里要注意,这些知识是BEV感知的数学地基,绕不过去的。

核心观点:多视图几何是连接2D图像与3D世界的桥梁。没有它,BEV感知就是空中楼阁。

多视图几何基础 对极几何 本质矩阵 E 基础矩阵 F 单应矩阵 H 三角化 PnP 问题 BEV 感知中的几何约束 核心概念 关键算法 应用落地

1.1 对极几何——两视图之间的约束

先讲对极几何。这东西说白了就是描述两个相机看同一个点时的几何关系。我刚开始接触时也觉得抽象,后来在项目中调试双目测距,才真正理解它的价值。

对极几何的核心就一句话:左图上的一个点,在右图上对应的搜索范围是一条线,而不是整张图。这条线就叫「极线」。

我的经验:在实际的BEV项目中,对极几何帮我们大幅缩小了特征匹配的搜索空间。原来要遍历整张图找匹配点,现在只需要沿着极线搜就行,速度提升至少10倍。

对极几何有几个关键元素:

  • 基线:两个相机光心的连线
  • 极点:基线与成像平面的交点
  • 极平面:空间点与两个光心确定的平面
  • 极线:极平面与成像平面的交线

你想想看,如果两个相机是平行放置的(比如车载双目相机),极线就是水平的。这意味着左右图的匹配点只在同一行上搜索——这就是为什么很多双目算法只做水平方向的匹配。

1.2 本质矩阵 E——已知相机内参时的神器

本质矩阵 E 是什么?它是对极几何的数学表达。但有个前提:你得知道相机的内参。

E 矩阵是一个 3x3 的矩阵,秩为2。它把左图上的一个点,映射到右图上的极线。公式长这样:

// 本质矩阵约束
x2^T * E * x1 = 0

// 其中 x1, x2 是归一化平面上的点坐标
// E = [t]× * R
// [t]× 是平移向量的反对称矩阵
// R 是旋转矩阵

我记得有一次在项目中,用 E 矩阵做视觉里程计。当时采集的数据里相机内参标定得不太准,结果 E 矩阵分解出来的旋转和平移全是错的。后来重新标定了内参,一切才恢复正常。所以这里要提醒大家:E 矩阵对相机内参非常敏感。

避坑指南:我曾经在实车测试时发现,车辆颠簸会导致相机内参轻微变化。如果你用出厂标定的内参算 E 矩阵,结果可能偏差很大。建议在车上做一次在线标定,或者用鲁棒性更强的算法。

1.3 基础矩阵 F——不知道内参也能用

基础矩阵 F 和 E 矩阵本质是一回事,但 F 矩阵不需要知道相机内参。它直接操作像素坐标:

// 基础矩阵约束
p2^T * F * p1 = 0

// 其中 p1, p2 是像素坐标
// F = K2^(-T) * E * K1^(-1)
// K1, K2 是两个相机的内参矩阵

说白了,F 矩阵就是把 E 矩阵「包裹」了一层内参信息。在自动驾驶场景中,如果你用的是不同型号的相机(比如前视广角+侧视长焦),F 矩阵就特别有用——它不需要你精确知道每个相机的内参。

但要注意,F 矩阵的自由度是7(因为尺度等价性和秩为2的约束),而 E 矩阵的自由度是5。这意味着 F 矩阵需要更多点对来求解,而且对噪声更敏感。

矩阵 自由度 需要内参 适用场景
本质矩阵 E 5 是 已知内参的双目/多目
基础矩阵 F 7 否 未知内参或混合相机
单应矩阵 H 8 否 平面场景或纯旋转

1.4 单应矩阵 H——平面场景的利器

单应矩阵 H 和前两个不太一样。它描述的是同一个平面在两个视图之间的映射关系。说白了,如果场景中所有点都在一个平面上(比如地面、墙面),那么 H 矩阵就能完美描述它们之间的变换。

在BEV感知中,单应矩阵用得特别多。为什么?因为地面就是一个平面。我们可以用 H 矩阵把前视相机拍到的地面区域,直接投影到鸟瞰图上。

// 单应矩阵约束
p2 = H * p1

// H 是一个 3x3 矩阵
// 对于地面平面 n^T * X = d
// H = K2 * (R - t * n^T / d) * K1^(-1)

实际应用:在BEV感知中,我们经常用单应矩阵做「逆透视映射」(IPM)。把前视图像中的地面区域,投影到俯视图上。这样车道线、路沿等地面元素就能在BEV空间里直接处理了。

但这里有个坑:单应矩阵假设所有点都在同一个平面上。如果场景中有立体的物体(比如行人、车辆),用 H 矩阵投影就会产生畸变。我见过一些新手直接把整张图做 IPM,结果行人被拉成了长条——嗯,这就是没理解单应矩阵的适用范围。

1.5 三角化——从2D到3D的逆推

三角化,说白了就是已知两个视图的匹配点,以及相机之间的位姿,反推出空间点的3D坐标。这是BEV感知中获取深度信息的关键步骤。

原理很简单:两条射线(从两个相机光心出发,经过匹配点)的交点就是空间点。但实际中因为噪声,两条射线往往不相交。所以我们要找「最接近」两条射线的点。

// 三角化的线性解法
// 对于匹配点 x1, x2 和投影矩阵 P1, P2
// 构建线性方程组:
// x1 × (P1 * X) = 0
// x2 × (P2 * X) = 0
// 用SVD求解 X

我个人习惯用「中点法」做三角化——取两条射线距离最近的两个点,取它们的中点作为3D点。这个方法简单,而且在实际项目中效果不错。

我的经验:三角化的精度很大程度上取决于两个相机的基线长度。基线越长,深度估计越准。但车载相机基线不能太长(车就那么宽),所以远距离物体的深度估计误差会很大。在BEV感知中,我一般只对30米以内的物体做三角化,再远就用其他方法了。

1.6 PnP问题——已知3D求2D位姿

PnP(Perspective-n-Point)问题和三角化正好相反。它是已知一些3D点及其在图像上的2D投影,求相机相对于这些3D点的位姿(旋转和平移)。

在自动驾驶中,PnP用得最多的地方是视觉定位。比如我们知道地图上一些路标的3D位置,然后在图像中检测到这些路标,就能算出当前相机(也就是车)的位置。

PnP问题有很多解法:

  • P3P:只用3个点,速度快但容易受噪声影响
  • EPnP:用4个以上点,精度和鲁棒性更好
  • DLT:直接线性变换,简单但需要至少6个点
  • 迭代法:比如Levenberg-Marquardt优化,精度最高但慢
// OpenCV中的PnP求解
// 输入:3D点、2D点、相机内参、畸变系数
// 输出:旋转向量、平移向量

bool success = cv::solvePnP(
    objectPoints,   // 3D点
    imagePoints,    // 2D点
    cameraMatrix,   // 内参矩阵
    distCoeffs,     // 畸变系数
    rvec,           // 输出旋转向量
    tvec            // 输出平移向量
);

避坑指南:我曾经在项目中用PnP做车辆定位,发现结果经常跳变。后来排查发现,是因为用了共面的3D点(比如地面上的标记点)。当所有3D点共面时,PnP问题会有歧义——说白了就是解不唯一。解决方案是加入非共面的点,或者用RANSAC做鲁棒估计。

小结

这一章我们聊了多视图几何的六个核心概念。它们之间的关系是这样的:

  • 对极几何是理论基础,描述了视图之间的约束关系
  • 本质矩阵 E 和 基础矩阵 F 是对极几何的数学表达,区别在于是否知道内参
  • 单应矩阵 H 专门处理平面场景,在BEV的IPM中特别有用
  • 三角化从2D匹配反推3D位置
  • PnP从3D-2D对应关系反推相机位姿

这些知识在BEV感知中无处不在。比如BEV空间中的深度估计、多相机融合、时序对齐,都离不开这些几何基础。我个人觉得,花时间把这些概念吃透,后面学BEV会轻松很多。

可可精品资料库