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能成为主流?我总结了三个核心优势:

  1. 统一坐标系,天然融合

    所有传感器(摄像头、激光雷达、毫米波雷达)的输出,都转换到BEV空间。不需要复杂的跨传感器匹配。

  2. 时序信息自然对齐

    在BEV空间里做时序融合,比在2D图像上做容易得多。目标运动轨迹是连续的,不会因为视角变化而跳变。

  3. 端到端可学习

    从图像到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。从数据准备到模型训练,每一步我都会给出可运行的代码。

嗯,到时候见。