1. BEV感知概览:从2D视觉到BEV的演进
大家好,欢迎来到这门实战课的第一章。
我是谁不重要,重要的是——接下来几个月,我会带你亲手搭建一套能上路的BEV感知系统。嗯,这条路我走过,踩过的坑不少,但收获也很大。
今天我们先聊聊:为什么整个行业都在往BEV方向转?
1.1 从2D视觉到BEV的演进
先回忆一下传统的2D感知方案。
你想想看,几年前做自动驾驶感知,主流做法是什么?
- 前视摄像头做目标检测,输出2D框
- 侧视摄像头做盲区监测
- 后视摄像头做倒车辅助
每个摄像头各干各的,互不干扰。听起来挺合理?
但实际跑起来就发现问题了——同一个目标,在不同摄像头画面里出现,怎么关联?
核心痛点:2D感知缺乏统一的物理空间坐标系。每个摄像头看到的都是像素坐标,没法直接融合。
我记得2020年做的一个项目,前视检测到一辆白色轿车,侧视也检测到一辆白色轿车。但它们是同一辆车吗?
为了判断这个,我们得写一堆复杂的匈牙利匹配算法、卡尔曼滤波跟踪……代码量巨大,效果还差。
说白了,2D感知是「各说各话」,没有全局视角。
那BEV(Bird's Eye View,鸟瞰视角)解决了什么?
它把所有传感器的检测结果,统一投影到自车为中心的俯视图上。所有目标都在同一个坐标系里,位置、速度、朝向一目了然。
我的个人习惯:做BEV感知时,我会把整个场景想象成一个「上帝视角的棋盘」。每个目标就是棋盘上的棋子,位置精确到厘米级。
1.2 BEV感知的核心优势
为什么BEV能成为主流?我总结了三个核心优势:
- 统一坐标系,天然融合
所有传感器(摄像头、激光雷达、毫米波雷达)的输出,都转换到BEV空间。不需要复杂的跨传感器匹配。
- 时序信息自然对齐
在BEV空间里做时序融合,比在2D图像上做容易得多。目标运动轨迹是连续的,不会因为视角变化而跳变。
- 端到端可学习
从图像到BEV特征的映射,可以用神经网络直接学习。不需要手工设计几何变换规则。
注意:BEV不是万能的。它最大的代价是计算量——把2D图像投影到3D空间,再压缩到BEV,中间的信息损失和计算开销都不小。
我曾经在一个嵌入式平台上尝试部署BEV模型,结果帧率只有5FPS。后来花了两个月做模型剪枝和量化,才勉强跑到15FPS。嗯,这个坑后面会详细讲。
1.3 主流BEV方案对比:LSS、Transformer、IPM
目前主流的BEV方案有三条技术路线。我分别说说它们的核心思想和适用场景。
1.3.1 IPM(逆透视映射)
IPM是最早的方案,说白了就是纯几何变换。
假设地面是平的,通过相机内外参,把图像像素映射到BEV空间。
# 伪代码示例:IPM变换
def ipm_transform(image, camera_matrix, ground_plane):
# 1. 计算单应性矩阵 H
H = compute_homography(camera_matrix, ground_plane)
# 2. 应用透视变换
bev_image = cv2.warpPerspective(image, H, (bev_width, bev_height))
return bev_image
优点:速度快,不需要训练。
缺点:依赖地面平坦假设,遇到坡道、颠簸路面就崩了。
避坑指南:我曾经在高速场景用IPM,效果还不错。但一进地下车库,地面有坡度,投影出来的车辆位置直接偏移了2米多。所以IPM只适合结构化道路。
1.3.2 LSS(Lift-Splat-Shoot)
LSS是NVIDIA在2020年提出的方案。核心思想是:先提升(Lift),再铺开(Splat)。
- Lift:为每个像素预测深度分布,把2D特征提升到3D空间
- Splat:把3D特征池化到BEV网格
# LSS核心流程(简化版)
def lift_splat(features, depth_probs):
# features: [B, C, H, W] 图像特征
# depth_probs: [B, D, H, W] 深度概率分布
# 1. 外积得到3D特征
# 2. 根据相机参数投影到BEV网格
# 3. 体素池化(voxel pooling)
bev_features = voxel_pooling(features_3d, depth_probs)
return bev_features
优点:能处理任意数量的摄像头,对深度估计有显式建模。
缺点:深度预测不准时,BEV特征会模糊。而且计算量集中在深度分支上。
我的经验:LSS在近距离(0-30米)效果很好,但远距离(50米以上)深度预测方差大,BEV特征会「糊」成一团。我一般会在深度分支上加一个不确定性估计模块,效果提升明显。
1.3.3 Transformer方案(BEVFormer等)
这是目前最火的方案。用Transformer的注意力机制,直接在BEV空间查询图像特征。
# BEVFormer核心思想(伪代码)
def bev_former(images, bev_queries):
# bev_queries: [N_bev, C] 可学习的BEV位置编码
# images: [N_cam, C, H, W] 多视角图像
for layer in transformer_layers:
# 1. 可变形注意力:从图像中采样特征
image_features = deformable_attention(bev_queries, images)
# 2. 自注意力:BEV内部交互
bev_queries = self_attention(bev_queries + image_features)
return bev_queries # 最终BEV特征
优点:不需要显式深度估计,端到端学习。远距离效果比LSS好。
缺点:训练收敛慢,对显存要求高。我刚开始训练BEVFormer时,8张A100跑了一个星期才收敛。
1.4 三种方案对比总结
| 方案 | 核心思想 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| IPM | 纯几何变换 | 速度快、无需训练 | 依赖地面平坦假设 | 结构化道路、低速场景 |
| LSS | 深度估计+体素池化 | 多相机融合、显式深度 | 远距离模糊、计算量大 | 中近距离、多传感器融合 |
| Transformer | 注意力机制查询 | 远距离好、端到端 | 训练慢、显存高 | 高精度需求、有充足算力 |
我的建议:如果你刚入门,先从LSS开始。它原理直观,代码实现相对简单。等理解了BEV的基本流程,再挑战Transformer方案。
1.5 本章小结
好了,第一章的内容就到这里。
我们聊了:
- 为什么从2D转向BEV——统一坐标系,解决多传感器融合难题
- BEV的三大核心优势——统一、时序、端到端
- 三种主流方案的对比——IPM、LSS、Transformer
下一章,我会带你亲手搭建一个LSS模型的训练pipeline。从数据准备到模型训练,每一步我都会给出可运行的代码。
嗯,到时候见。