第7章第三阶段:自动驾驶感知基础

第7章:3D 视觉与 BEV 感知

从零实现 BEV 感知系统(LSS + BEVFormer),掌握多视图几何、坐标变换、时序融合与多传感器融合。

LSSBEVFormerBEVDet多视图几何时序BEV

从多相机到鸟瞰图 -- 自动驾驶感知的核心


前言

本章面向有 CNN 感知经验的自动驾驶算法工程师,讲解 BEV 感知的两大主流范式:LSS 和 BEVFormer。

学完本章你将获得:

- LSS 视图变换的完整数学推导

- 相机几何的工程实现能力

- BEVFormer 的 Deformable Cross-Attention 理解

- 一套完整可运行的 BEV 感知代码


第一部分:为什么需要 BEV 感知?

1.1 传统透视感知的局限

传统自动驾驶感知在透视图像上进行 2D 检测,存在三个根本问题:

1. 尺度歧义:远处物体在图像中很小,近处很大,同一个物体在不同距离的呈现完全不同

2. 遮挡问题:透视图像中的遮挡难以推理,被遮挡物体可能完全不可见

3. 多相机融合困难:6 个相机各看各的,无法形成统一的空间理解

1.2 BEV 的解决方案

BEV (Bird's Eye View) 将感知空间从透视图像转换到鸟瞰图:

- 尺度一致:BEV 空间中的物体大小由其物理尺寸决定,与距离无关

- 适合规划:轨迹和规划天然在 BEV 空间中进行

- 多传感器融合:LiDAR、Radar、地图都可以在 BEV 空间统一表示


第二部分:相机几何基础

2.1 针孔相机模型

核心变换链:


像素坐标 (u, v, d) → 相机坐标 (x_c, y_c, z_c) → 世界坐标 (x_w, y_w, z_w)

关键公式:

像素到相机:


x_c = (u - cx) * z / fx
y_c = (v - cy) * z / fy
z_c = z

相机到世界(刚性变换):


[x_w, y_w, z_w]^T = R @ [x_c, y_c, z_c]^T + t

2.2 内参与外参

参数类型 含义 示例值
fx, fy X/Y 方向焦距 800.0
cx, cy 主点(光心) (800, 450)
R (3x3) 旋转矩阵 相机朝向
t (3x1) 平移向量 相机安装位置

2.3 多相机系统

nuScenes 标准 6 相机配置:

- CAM_FRONT(前视)

- CAM_FRONT_LEFT / CAM_FRONT_RIGHT(前侧视)

- CAM_BACK(后视)

- CAM_BACK_LEFT / CAM_BACK_RIGHT(后侧视)

每个相机有独立的内参和外参,但共享同一个世界坐标系。


第三部分:LSS (Lift-Splat-Shoot)

3.1 Lift -- 将图像特征提升为 3D 视锥

核心思想:对每个像素预测其在各个深度 bin 上的概率分布。


输入:图像特征 F ∈ R^{C×H×W}
输出:视锥特征 F_frustum ∈ R^{C×D×H×W}

Step 1: 预测深度分布 D_dist ∈ R^{D×H×W}(softmax over depth bins)
Step 2: 将图像特征与深度分布外积:F_frustum = F_unsqueeze ⊙ D_dist_unsqueeze

深度分布的学习通常需要深度监督(LiDAR 点云投影提供深度 ground truth)。

3.2 Splat -- 将 3D 视锥投影到 BEV

核心思想:利用相机几何将每个视锥体素映射到 BEV 栅格。


Step 1: 计算每个视锥体素的世界坐标
Step 2: 将世界坐标映射到 BEV 栅格索引
Step 3: Voxel Pooling -- 同一 BEV 栅格内的所有视锥特征做 sum pooling

Voxel Pooling 的实现技巧:


# 使用 scatter sum 实现高效的 BEV 聚合
bev.scatter_add_(0, bev_indices, frustum_features.view(-1, C))

3.3 Shoot -- BEV 特征到任务输出

BEV 特征通过标准的卷积网络进行后处理,输出:

- 3D 检测(中心、尺寸、朝向、类别)

- BEV 分割(可行驶区域、车道线)

- 未来的运动预测


第四部分:BEVFormer

4.1 设计动机

LSS 依赖显式深度估计(可能不准确),BEVFormer 使用可学习的 BEV Queries 隐式地从图像中查询信息。

4.2 核心组件

可学习的 BEV Queries:


Q_bev ∈ R^{N_bev×C}  其中 N_bev = H_bev × W_bev

每个 BEV Query 对应 BEV 空间中的一个位置,通过空间交叉注意力从多相机图像中聚合信息。

Spatial Cross-Attention:


BEV Query 对应世界坐标 (x, y) → 投影到各相机像素 (u_i, v_i)
→ 在 (u_i, v_i) 周围采样 Deformable Points
→ 用 Deformable Attention 聚合多相机特征

时序自注意力 (Temporal Self-Attention):


当前帧 BEV Query → 与历史 BEV 特征做自注意力
→ 历史 BEV 特征先按自车运动对齐到当前帧坐标系

4.3 Deformable Attention

与标准 Attention 不同,Deformable Attention 只在少数采样点计算注意力:


DeformAttn(q, p, x) = Σ W_m [Σ A_mqk · W_m' x(p + Δp_mqk)]

其中 p 是参考点,Δp 是可学习的偏移量。

优点:

- 计算复杂度与图像大小无关(只计算 K 个采样点)

- 自然地处理多尺度特征

4.4 时序对齐

自车运动补偿:


当前帧坐标系 = 自车运动 × 历史帧坐标系
T_align = T_ego_t-1^(-1) @ T_ego_t

将历史 BEV 特征通过 T_align 变换到当前帧后再做注意力。


第五部分:3D 检测头

5.1 DETR-style Detection Head

使用可学习的 Object Queries,通过 Transformer Decoder 交叉注意力从 BEV 特征中提取物体信息:


Object Queries (N=900) × Cross-Attention(BEV Features)
→ 每个 Query 预测一个 3D 框或 "no object"

5.2 3D 框参数化

每个框用 9 个参数表示:

- 中心坐标: (x, y, z)

- 尺寸: (w, l, h)

- 朝向: sin(θ), cos(θ)

- 速度: (vx, vy)

5.3 匹配与 Loss

使用 Hungarian 匹配(二分图匹配)将预测框与 GT 框配对:

- 分类 Loss: Focal Loss

- 回归 Loss: L1 Loss

- IoU Loss: 3D IoU


最佳实践与常见问题

Q: LSS vs BEVFormer 如何选择?

- 快速原型和实时系统:LSS(纯卷积,速度快)

- 追求最高精度且有足够算力:BEVFormer

- 需要时序信息:BEVFormer(原生支持)

- 2025 年趋势:BEVFormer 及其变体(BEVFormer v2, BEVDepth)

Q: 深度监督对 LSS 有多重要?

非常重要。没有深度监督,LSS 的深度估计会退化,导致 BEV 特征质量下降。

建议使用 LiDAR 点云投影作为深度 GT,loss weight 设为 0.01-0.1。

Q: BEV 分辨率如何选择?

- 0.5m/格 (200x200):标准选择,适合城市驾驶

- 0.25m/格 (400x400):更高精度,但计算量 4x

- 1.0m/格 (100x100):高速巡航,精度要求低

Q: 如何处理相机外参标定误差?

- 训练时加入外参噪声(数据增强)

- 使用可学习的外参(让网络适应微小偏移)

- 在线标定模块


下一步

完成本章后,建议:

1. 运行演示脚本,观察 BEV 特征的可视化

2. 尝试不同的 BEV 分辨率,对比效果和速度

3. 阅读 LSS 和 BEVFormer 原始论文

4. 进入第8章:Occupancy Network


本章项目地址: vla_learn/chapter07_bev_perception/
预计学习时间: 2-3 天(含代码阅读和理解)