规划器想问的是“前方 8 米、偏左 2 米这一格里有没有东西”,可 6–8 个相机交出来的是各自视角里的像素,单张图像里每个像素离车多远并不知道。把所有相机的特征放进同一张俯视网格(bird's-eye view,BEV),规划才有统一的米制坐标;难点始终是深度:lift-splat 让每个像素沿视线按一个深度分布把特征摊开,BEV query 反过来让每个格子去图像里取特征,占用网格再把输出细化到“这块空间有没有被占”,不必先认出是什么。
待审核草稿。 这一篇还没有经过站主审阅,事实、取舍和措辞都可能修改;引用前请回到文中链接的一手资料核对。
为什么要一张俯视图
相机图像是透视的:远处的车小,近处的车大,一辆车跨在两个相机的边界上会被切成两半。规划要的是米制、俯视、所有传感器共用的坐标:车道朝哪个方向,前车离我几米,旁边那格能不能开进去。BEV 网格把自车周围划成格子,每格存一个特征向量;检测头、地图头、规划头都在这张网格上工作。lidar 点云本来就带三维坐标,可以直接投进去;相机缺的正是深度。
两个常见设置:Lift-Splat-Shoot(Philion 与 Fidler,ECCV 2020)在自车周围 ±50 m 内按 0.5 m 一格,得到 200×200 的网格;BEVFormer(ECCV 2022)用 ±51.2 m、0.512 m 一格,也是 200×200。若每格存 64 个 float16 通道,一张 BEV 特征图约 $200\times200\times64\times2\approx5.1$ MB,这是教学估算。
针孔相机模型里,一个像素对应一条从相机中心出发的射线,射线上每一点都投到同一个像素上。只看一张图,就不知道这个像素里的东西在射线上的哪个位置。投影怎样推导,见相机几何。
先算一次:一个像素怎样摊进鸟瞰格子
下面的数字都是教学设定。相机装在自车原点,朝前($x$ 轴)。某个像素在图像中心偏左,它的射线满足 $y=0.25\,d$:$d$ 是沿光轴的深度,$y$ 是向左的横向距离。只看俯视平面,暂时不管高度。
LSS 论文 §3.1 的做法:网络对每个像素输出一个上下文特征 $c\in\mathbb R^C$,和一个在 $|D|$ 个离散深度上的分布 $\alpha$;放在深度 $d$ 那一点上的特征是两者相乘:
$$ c_d=\alpha_d\,c,\qquad \sum_{d\in D}\alpha_d=1 . $$
设深度只有 4 档 $D=\{4,8,12,16\}$ m,网络输出 $\alpha=(0.1,0.6,0.2,0.1)$,$c=(2,1)$。这里 $C=2$,两个通道可以想成“像车”和“像路面”的程度;真实网络的通道没有这么直白的含义,这样写只是为了好读。BEV 格子取 8 m × 8 m(论文是 0.5 m,这里放大是为了让一个格子里落进两个点)。
| 深度 $d$ | $\alpha_d$ | 俯视坐标 $(x,y)$ | 特征 $c_d=\alpha_d c$ | 落进的格子 |
|---|---|---|---|---|
| 4 m | 0.1 | (4, 1) | (0.2, 0.1) | $x\in[0,8)$ |
| 8 m | 0.6 | (8, 2) | (1.2, 0.6) | $x\in[8,16)$ |
| 12 m | 0.2 | (12, 3) | (0.4, 0.2) | $x\in[8,16)$ |
| 16 m | 0.1 | (16, 4) | (0.2, 0.1) | $x\in[16,24)$ |
这是 lift:一个像素变成射线上 4 个带特征的点。接着 splat:论文把每个点分到最近的 pillar(高度无限的竖直格子),同一格里的特征直接相加(sum pooling)。4 个点的 $y$ 都在 $[0,8)$ 里,于是:
- 格子 $[0,8)$:$(0.2,0.1)$
- 格子 $[8,16)$:$(1.2+0.4,\;0.6+0.2)=(1.6,0.8)$
- 格子 $[16,24)$:$(0.2,0.1)$
三格加起来是 $(2.0,1.0)=c$。因为 $\sum\alpha_d=1$,这个像素的特征总量不变,只是沿射线分配到不同距离。如果车真在 8 m 处,它“像车”的特征有 80% 落进了对的格子,10% 落在更近的格子,10% 落在更远的格子。相机 BEV 常见的“沿视线方向拖尾”就是这样来的。
在论文的真实分辨率下(0.5 m 一格、深度每 1 m 一档),同一条射线上相邻的深度点很少落进同一格;相加更多发生在相邻像素之间,以及两个相机视野重叠的区域。
换一个条件:分布变尖、变平,或者放错了
- 变尖。 $\alpha=(0,1,0,0)$:全部特征落进 $[8,16)$。这相当于先估一个深度再投影;论文把它比作 pseudo-lidar。
- 变平。 $\alpha=(0.25,0.25,0.25,0.25)$:每个深度点都是 $(0.5,0.25)$,$[8,16)$ 得到 $(1.0,0.5)$,另外两格各得 $(0.5,0.25)$。射线上每个位置的表示都一样,论文把它比作 OFT。论文的说法是:网络因此可以自己选择,是把特征放到一个位置,还是在深度说不准时沿整条射线摊开。
- 放错。 车其实在 16 m,$\alpha$ 仍然是 $(0.1,0.6,0.2,0.1)$:对的格子 $[16,24)$ 只拿到 10%,大部分落在 $[8,16)$。在俯视图(view)里,这辆车看起来近了大约 8 m。相机的深度误差直接变成 BEV 里的位置误差,这是相机加 lidar 融合最直接的动机。
论文里的真实设置与开销
LSS 论文 §4.1 的设置:深度限定在 4 m 到 45 m 之间,每 1 m 一档;输入图像缩放、裁剪到 128×352;BEV 网格 200×200。一张 $H\times W$ 的特征图会生成 $|D|\cdot HW$ 个点(这里 $|D|=41$),再乘以相机数,点数很大。论文 §4.2 用一个 “cumsum trick” 做 sum pooling:按格子编号把点排序,对特征做累加和,再在每段边界处相减;他们推了这一层的解析梯度,训练快了 2 倍。论文报告整个前向在一块 Titan V 上跑 35 Hz,这是 2020 年硬件上的作者测量。
名字里的 shoot 是规划:网络在 BEV 上输出一张代价图,把 1,000 条模板轨迹(对专家轨迹做 K-means 得到)“打”到代价图上,沿轨迹累加代价,训练时当作分类,测试时取代价最低的那条。这是第 2 篇“候选(candidate)轨迹加打分”的一个学习版本。
反过来取:BEV query
BEVFormer 不从像素往外推,而是从格子往图像里拉。它为每个 BEV 格子准备一个可学习的 query。论文 §3.3 和 §4.2 的做法是:把每个格子升成一根竖直的柱子,在 −5 m 到 3 m 的高度之间均匀取 4 个参考点;用相机内外参把这些点投到图像上,只在“打中”的相机里取特征;每个投影点附近用 deformable attention 再采 4 个点。另有 temporal self-attention,把按自车运动对齐过的上一时刻 BEV 融进来。摘要报告在 nuScenes test 上 NDS 56.9,比之前最好的方法高 9.0。

用前面同一个相机看:格子中心 $(12,3)$ 满足 $3=0.25\times12$,正好在刚才那条射线上,投到同一个像素。$(4,1)$、$(8,2)$、$(16,4)$ 也都投到同一列。如果每个格子只是照搬那个像素的特征,这 4 个格子会得到一模一样的东西:射线上的歧义并没有消失,只是换了地方。能把它们分开的是:同一个格子被另一个相机、或在下一时刻从另一个角度看到;不同高度的参考点投到不同的像素行,车身和路面在不同高度上看起来不一样;以及注意力权重本身是学出来的。
| 对比 | Lift-splat(推) | BEV query(拉) |
|---|---|---|
| 方向 | 每个像素把特征推到射线上多个深度 | 每个 BEV 格子去图像里取特征 |
| 深度怎么处理 | 显式预测深度分布 $\alpha$ | 不预测深度,靠多视角、多高度采样和注意力 |
| 计算随什么增长 | 像素数 × 深度档数 | 格子数 × 参考点数 × 采样点数 |
| 典型失败 | 深度分布错,特征沿射线拖尾 | 投到同一像素的格子分不开,要靠时序和多视角 |
Tesla 在 2021-08-19 的 AI Day 上介绍过同一类思路:用铺满位置编码(positional encoding)的输出空间栅格去 attend 图像特征,把图像空间转成 BEV,再用特征队列和视频模块做时序融合(视频,据演讲自动字幕)。那是 Tesla 早期模块化栈的描述。
不铺满网格:稀疏 query
200×200 的网格里大部分格子是空路面。另一条路线不建稠密 BEV,只用一组 object query。PETR(ECCV 2022)的摘要说,它把三维坐标的位置信息编码进图像特征,object query 直接 attend 这些“知道三维位置”的特征去做检测,报告 nuScenes 50.4 NDS、44.1 mAP。StreamPETR 按摘要把 object query 逐帧往后传,做时序融合;Sparse4D 做稀疏的时空采样。SparseDrive 把这条路线接到了规划:全稀疏的感知,加一个并行的运动规划器(据其 README)。
好处是计算随 query 数而不是网格面积增长;代价是不会白送一张稠密的可行驶区域图。不是“物体”的东西,比如路面形状、一堆碎石,需要另加地图头或占用头。
相机加 lidar:BEVFusion
BEVFusion(ICRA 2023)把相机特征和 lidar 特征放进同一张 BEV 里再融合,服务多个任务。摘要报告:nuScenes 三维检测的 mAP 和 NDS 各高 1.3%,BEV 地图分割的 mIoU 高 13.6%,计算量低 1.9 倍;优化 BEV pooling 后,视角转换的延迟降低 40 倍以上。放回上面的例子:lidar 直接测出 16 m,特征就不必靠 $\alpha$ 去猜。
工业界两种立场都有。Waymo 2025-12 的 Foundation Model 用一个 Sensor Fusion Encoder 融合相机、lidar 和 radar(博客);Tesla 在 2025 年第一季度股东信中描述的是纯视觉、端到端神经网络的架构。
占用:先问占没占,不先问是什么
一个 3D 框通常是中心 3 个数、尺寸 3 个数、朝向 1 个数,再加一个类别。横在车道上的梯子、伸出来的树枝、形状不规则的货物,框都描述不好;类别表里没有的东西,检测器也可能直接漏掉。Occ3D(NeurIPS 2023)的摘要把占用预测定义为估计场景中每个位置的占用状态和语义,用来弥补框在细粒度几何和词表(vocabulary)外物体上的不足。
CVPR 2023 占用预测挑战赛用 Occ3D-nuScenes:体素 0.4 m,网格 200×200×16,18 个类别(其中一类是“空”,free),推理时只用相机,按 mIoU 排名。算一下:水平方向 $200\times0.4=80$ m 见方,竖直方向 $16\times0.4=6.4$ m 高;每帧 $200\times200\times16=640{,}000$ 个体素,每个都要给一个类别。按技术报告的摘要,冠军 FB-OCC 的 mIoU 是 54.19%。
mIoU 先对每个类别算交并比,再对类别取平均。比如“车”这一类,预测了 120 个体素,真值 100 个,重合 80 个:
$$ \text{IoU}=\frac{80}{120+100-80}=\frac{80}{140}\approx0.571 . $$
稀有类别和常见类别权重相同,所以几个小类做得差,mIoU 会明显下降。
Tesla 在 2022 年两次介绍过占用网络,都是演讲,下面据自动字幕转述。CVPR 2022 WAD 主题演讲(2022-06-20,视频):8 个相机的视频流一起输出体素占用概率和占用流(occupancy flow),用带三维位置编码的 query 去 attend 多相机图像特征;演讲给的数字是 8 个 1.2 MP、36 fps 的相机,网络在 10 ms 内跑完(公司自报)。AI Day 2022(2022-09-30,视频):输入是未经 ISP 处理的 12 位原始光子计数图像;固定体素对规划不够精细,所以每个体素带特征,可以用一个 MLP 在任意位置查询;训练用的是自动标注,不靠人工标。
标签从哪来
每帧 64 万个体素,不可能人工逐个标。几种做法:
- 把稀疏的 lidar 补成稠密体素。 Occ3D 的摘要列出三步:体素稠密化、遮挡推理、用图像引导细化体素,得到“考虑可见性”的标签。SurroundOcc(ICCV 2023)按摘要用多帧 lidar 加 Poisson 重建生成稠密真值。
- 离线自动标注。 车载模型只能看过去;离线标注可以看整段序列的前后帧,用更大的模型。Waymo 的 3D Auto Labeling(Qi 等,2021)就是从整段点云序列离线检测物体。
这样得到的标签继承了 lidar 的盲区:被挡住、没扫到的体素没有可靠真值。所以评测常常只在“可见”体素上算分:CVPR 2023 挑战赛的 README 写明,只在当前相机看得到的体素上算 mIoU,看不见的体素不计入。读别的结果时要看清楚用的是哪一种。
进了端到端栈,它们变成了什么
Tesla 在 2025 年 10 月的 ICCV 演讲中说,显式感知现在是可选的辅助输出,同一个模型可以被要求输出占用、物体等(视频,据演讲自动字幕)。Waymo 的 Foundation Model 仍有一个 World Decoder 输出其他交通参与者的行为、地图和轨迹。Bench2Drive 0.0.4(2026-08)新增了占用模态。BEV 和占用没有消失:它们成了辅助监督、调试视图,以及安全检查能读懂的中间结果。
复现和排错时看什么
| 先试什么 | 应该观察什么 | 不能据此推出什么 |
|---|---|---|
| 用 lidar 深度替换预测的深度分布 | BEV 里物体不再沿视线拖尾,距离误差变小 | 相机深度估计已经够用 |
| 训练时随机丢掉一个相机 | 测试时缺相机的退化变小;LSS 论文报告这样训出的模型在 6 个相机都在时也最好 | 冗余相机可以省掉 |
| 训练和测试时给外参加噪声 | LSS 论文报告:测试噪声小时不加噪声训练最好,噪声大时加噪声训练更稳 | 训练加噪声能抵消真实标定漂移 |
| 按距离分段算 mAP / mIoU | 远处是否明显变差 | 平均分好就说明远距离可靠 |
| 只在可见体素上评测 vs 全部体素 | 两个分数差多少 | 看不见的地方模型也猜对了 |
参考:Lift-Splat-Shoot · BEVFormer · BEVFusion · Occ3D。下一篇:预测与规划。相机投影见相机几何,用重建做驾驶仿真见三维重建与神经渲染。
本页术语 4
- 视图 view
- 同一个对象的一种侧面表示;用户可以同时有画像视图和历史视图
- 候选 candidate
- 召回阶段捞出来、等待精排挑选的内容
- 位置编码 positional encoding
- 把「第几个 token」的信息注入表示
- 词表 vocabulary
- 模型能输出的所有 token 的集合