1. BEV感知概述:从2D视觉到BEV的演进

各位同学好,我是这门课的主讲。今天咱们聊聊BEV感知——这个在自动驾驶圈子里火得不行的话题。

说实话,我刚开始做感知那会儿,大家还在2D图像上画框框。那时候的算法,说白了就是“看图说话”。你给一张图,它告诉你哪里有车、哪里有行人。但问题来了——自动驾驶需要的是三维空间的理解,不是二维图片的解读。

从2D视觉到BEV的演进

为什么会从2D走向BEV?我给大家讲个真实经历。

几年前我在一个项目里做多传感器融合。当时用的是前视相机+毫米波雷达的方案。2D检测做得再好,到了3D空间里,位置估计总是有偏差。尤其是近距离的车辆,2D框看着挺准,但实际距离可能差个两三米。你想想看,这在高速上意味着什么?

传统2D感知的痛点很明显:

  • 视角局限:单张图像只能看到前方,无法感知周围360度
  • 尺度模糊:远处的小车和近处的大车,在图像上可能一样大
  • 缺乏深度:2D图像天然缺少距离信息
  • 时序不一致:不同帧之间的检测结果难以对齐

BEV(Bird's Eye View,鸟瞰视角)的出现,彻底改变了这个局面。它把感知问题从“图像空间”搬到了“物理空间”。

核心思想:BEV感知不是简单地“看图”,而是构建一个俯视的、以自车为中心的栅格地图。在这个地图上,每个格子对应真实世界的一个区域(比如0.1m×0.1m)。

BEV的核心优势

我个人觉得,BEV最大的优势就三个字:统一性

  1. 多传感器统一:相机、激光雷达、毫米波雷达,都可以投影到同一个BEV空间里。我在项目中做过相机+激光雷达的融合,以前要对齐两个坐标系,麻烦得要命。用了BEV之后,直接在同一个栅格上做特征融合,简单多了。
  2. 时序统一:不同时刻的感知结果,可以在BEV空间里对齐。这对跟踪和预测特别友好。
  3. 输出统一:检测、分割、轨迹预测,都可以在BEV空间里完成。不用再为每个任务设计不同的输出格式。

我的经验:BEV还有一个容易被忽略的好处——它天然适合做端到端学习。你不需要手工设计复杂的后处理逻辑,网络直接输出BEV空间里的目标位置和属性。我在部署时发现,BEV方案的代码量比传统方案少了将近一半。

主流BEV方案概览

目前主流的BEV方案有三条技术路线。我按自己的理解给大家梳理一下。

方案 核心思想 代表工作 我的评价
IPM 逆透视映射,几何变换 传统方法 简单但受限,适合结构化道路
LSS Lift-Splat-Shoot,深度估计+投影 BEVDet, BEVDepth 效果好,但深度估计是瓶颈
Transformer 注意力机制,隐式学习映射 BEVFormer, PETR 灵活强大,但计算量大

IPM(逆透视映射)

IPM是最早的BEV方案。它的原理很简单:假设地面是平的,通过相机内外参,把图像像素映射到地面坐标系。

嗯,这里要注意——IPM依赖“地面平坦”这个假设。我在一个坡道场景里吃过亏,IPM出来的BEV图完全变形了。所以它只适合结构化道路,比如高速公路。

# IPM的核心步骤(伪代码)
def ipm_transform(image, camera_matrix, homography):
    # 1. 计算单应性矩阵
    H = compute_homography(camera_matrix, ground_plane)
    # 2. 应用逆透视变换
    bev_image = cv2.warpPerspective(image, H, (bev_width, bev_height))
    return bev_image

LSS(Lift-Splat-Shoot)

LSS是NVIDIA在2020年提出的方案。它的思路很巧妙:先为每个像素估计一个深度分布,然后把图像特征“提升”到3D空间,再“拍平”到BEV平面。

我曾经在一个项目中复现过LSS。说实话,训练过程挺折磨人的。深度估计不准,BEV特征就全是噪声。后来我们加了一个深度监督分支,效果才稳定下来。

避坑指南:LSS的深度估计模块非常关键。我建议你在训练时,一定要给深度估计加一个辅助损失。否则网络很容易学到“平均深度”,导致BEV特征模糊。

Transformer方案

Transformer方案是这两年最火的。它用注意力机制,让网络自己学习从图像到BEV的映射关系。BEVFormer就是其中的代表作。

我个人觉得,Transformer方案最大的优势是灵活性。它不需要显式的深度估计,也不需要假设地面平坦。但代价是计算量大,部署起来比较头疼。

# BEVFormer的核心思想(简化版)
class BEVFormerLayer(nn.Module):
    def __init__(self):
        # 定义BEV query和可变形注意力
        self.bev_query = nn.Parameter(torch.randn(1, num_queries, dim))
        self.cross_attn = DeformableAttention()
    
    def forward(self, img_features, ref_points):
        # 用BEV query去查询图像特征
        bev_features = self.cross_attn(
            query=self.bev_query,
            key=img_features,
            value=img_features,
            reference_points=ref_points
        )
        return bev_features

如何选择方案?

很多同学问我:到底该选哪个方案?我的建议是:

  • 如果你做的是结构化道路(高速、城市快速路),IPM就够用了,简单高效
  • 如果你有深度传感器(激光雷达),LSS方案可以做得很好
  • 如果你追求极致性能,Transformer方案是首选,但要准备好算力
  • 如果你刚入门,我建议从LSS开始。它概念清晰,代码开源多,踩坑也有迹可循

总结一下:BEV感知的本质,是把感知问题从“图像空间”搬到“物理空间”。它统一了多传感器、时序和输出,是自动驾驶感知的未来方向。接下来的课程,我会带大家一步步实现一个完整的BEV感知系统。

好,这一章就到这里。下一章我们开始动手——搭建BEV感知的数据处理流水线。