文章目录
前言
端到端BEV提出人,2020超高引论文:
Lift, Splat, Shoot: Encoding Images from Arbitrary Camera Rigs by Implicitly Unprojecting to 3D
Lift,Splat,Shot:通过隐式非投影到3D来对来自任意相机组的图像进行编码
一、摘要与引言
我们提出了一个端到端架构,输入多视图相机,之后直接在BEV坐标系推断语义(车:蓝,可行驶区域:橙,车道:绿),然后将BEV预测投影回图像。网络输出的 BEV cost map 就像一个“路况热力图”,我们把模板轨迹“扔到” BEV cost map 上去计算“哪条路最安全、代价最小”,然后选那条作为规划结果。
很老的方案都是在摄像头坐标系做的分割
我们直接在鸟瞰图坐标系对多视图图像,进行端到端规划预测。
将单视图扩展到多视图有3个有价值的对称性:
Translation equivariance: 平移图像 → 检测结果也平移。
Permutation invariance: 摄像头顺序变化 → 输出不变。
Ego-frame isometry equivariance: 自车坐标旋转/平移 → 检测结果也旋转/平移。
目前简单方法的缺点:可能包含后处理或者是手写规则,会导致整个pipeline离散、不可微。但如果中间有不可微的后处理,梯度不能反向传播到相机特征 → 感知网络学不到教训 → 错误重复。
PS:端到端理解
只要网络里每个计算步骤都能写成一个数学上连续可导的函数,就能从最终loss往回推梯度。
比如卷积、矩阵乘法、加减、ReLU(除了0点)、sigmoid、softmax 等都是可微的。
而手写规则、if-else分支、阈值化、NMS 这类“硬判断”不可微。
我们提出了一个名为“Lift Splat”的模型,该模型保留了上述设计确定的3个对称性,同时也是端到端可微的。
二、方法
1. Lift:深度分布估计
目标:将每个图像从局部二维坐标系提升到所有相机共享的三维帧,也就是为每个像素生成所有可能深度的表示。
方法:为每个像素点定义一堆离散的深度值,在模型训练的时候,由网络自己选择合适的深度。
具体实现:在距离相机5m到45m的视锥内,每隔1m有一个模型可选的深度值(这样每个像素有41个可选的离散深度值)。
图中,相机视锥中一根射线上设置了10个可选深度值,第三个深度下特征最为显著,因此该位置的深度值为第三个。
2. Splat:投影
目的:计算像素的3D坐标,然后将这些3D点投影到BEV平面,生成稠密的特征图(C × H × W),供后续感知或规划使用。
方法:lift获得了像素的深度,加上相机的内参以及外参,可计算得出像素的3D坐标。
具体实现:借鉴了pointPillars中的做法,把Lift步骤得到的点云转换成Pillars, 其中Pillars是无限高的体素。具体做法是,把每个点分配到离他最近的Pillars中,然后执行求和池化得到C×H×W的张量,再对该张量进行2D CNN操作得到鸟瞰图的预测结果。
Pillars是什么:
- 在 x-y 平面上划分网格,每个格子是一个柱子(Pillar)。
- 所有落在该网格(同一 x-y 平面坐标范围内)的点云,都被放进同一个 Pillar。
- 这意味着 Pillar 本身不再有 z 方向的栅格划分(不像 voxel 会把空间切成 x-y-z 三维体素)。
- PointPillars 用 PointNet 小网络在每个 Pillar 内对这些点的 (x, y, z, 反射率等) 进行编码,得到一个柱体特征向量。所以 z 轴信息是通过特征编码进 pillar feature 里,而不是直接当作结构化的 z 维度。
池化:每个 Pillar(柱体)里面可能有几十个点 (x, y, z, intensity…),网络会用一个小的 MLP/PointNet 提取每个点的特征,然后 把该 Pillar 所有点的特征加和(或者加权加和),得到一个固定维度的 Pillar 特征向量。
张量Tensor:n维向量 [1,2,3,…,n]
C×H×W:
- C:通道数(Channel),类似彩色图像的 R/G/B 3 个通道。在 BEV 中,C 可能是 64、128 或更多,表示网络提取的各种特征。
- H:高度(Height),对应 BEV 网格的 Y 方向。
- W:宽度(Width),对应 BEV 网格的 X 方向。
对该张量进行2D CNN操作:
把这个三维特征图看作 H×W 的网格,每个网格上有 C 维特征,用卷积核(小窗口)在 H×W 平面上滑动,对 C 维特征做加权求和,从而生成新的特征图。
理解:
BEV特征图([C,H,W]):由 backbone(如 Lift-Splat、PointPillars)提取出来,C 可能是 64、128 或 256 这样的通道数。每个通道并不是直接表示“有车”或“有道”,而是不同的特征维度(类似于提取到的纹理、形状、边界信息的高维编码)。
Task Head(任务头):
- 检测头(Detection Head):对 BEV 特征图做卷积或 transformer query,输出 bounding box(汽车、行人位置)。
- 分割头(Segmentation Head):将 BEV 特征图解码成语义分割图,比如车道线、可行驶区域等。
- 占用预测头(Occupancy Head):预测每个 grid 在未来时刻的占用情况。
BEV特征图像一本“隐含了所有信息的压缩说明书”,需要不同的解码器(head)去读出“这里有车”、“这里是道路”。
LLS和pointPillars的不同之处:
普通的 sum pooling 需要在每个 pillar 内做 padding,这会浪费显存和算力。
作者采用 累积和 (cumsum) 技巧快速计算柱体特征,并确保梯度计算也能高效完成(保证可微性)。
这就是他们说的 “analytic gradient for autograd”——即这个操作的反向传播公式是解析可得的,而不是暴力计算。
(1)输入;在“lift”步骤中,为每个单独的图像生成一个截头圆锥体形状的点云(2);然后使用外部函数和内部函数将每个截头圆锥体投射到鸟瞰平面上(3);最后,BEVCNN处理BEV表示,以进行边界元法语义分割或规划(4)。
总结:通过 Lift-Splat(预测深度 + 几何映射)把多视图 2D 特征投影到 BEV,用 PointPillars 风格的 sum pooling 和高效的 cumsum 技巧来生成可训练的 BEV 特征图,从而可以端到端训练感知/规划任务。
3. Shoot:轨迹模板输入
Lift-Splat模型的关键:它支持端到端的cost map学习,且该地图可以用于运动规划,且仅仅只要camera即可。
规划模块完成的任务:使用推断的代价图进行规划,可以通过将不同轨迹shoot到BEV平面,评估代价后选择代价最小的轨迹。
我们将“规划”定义为预测自我车辆在K个模板轨迹上的分布,我们的方法受到了最近提出的神经运动规划器(NMP)的启发[41],这是一种基于点云和高清地图的架构,可以生成可用于对提出的轨迹进行评分的成本量。
总体流程:
3.1 CostMap生成
网络用多相机图像 → 生成 BEV cost map:地图上每个栅格都有“代价”(危险、不可驶入、红灯方向、障碍等都会体现为高代价)。
3.2 模板轨迹
手里有一堆预先整理好的 模板轨迹(模板轨迹),代表自车未来可能走的常见路径(直行、左转、右转、弯、减速弧线…)。
轨迹可视化
3.3 轨迹cost计算
把每条模板轨迹“射到”(shoot)BEV cost map 上:沿轨迹取样,把轨迹经过的所有栅格代价累加 → 得到该轨迹的总成本。
具体实现:对模板轨迹 𝜏𝑖沿路径逐点查 cost:,这是该轨迹的 能量/总代价(E 越大越差)。最后把能量转成概率分布(Boltzmann 分布)
这个从E到p的过程叫Softmax(-E)。
3.4 训练
选一条最接近专家轨迹的模板当标签,用交叉熵训练,让模型给它最高概率 → 间接教网络把专家行驶区域学成低代价。
具体而言
梯度从交叉熵损失回传 → 想让 p(τi∣o) 高→ 要让 Ei 小 → 要让该轨迹上所有 (x,y) 的 cost 低。
同时不在标签轨迹上的其它模板代价被相对推高(因为 softmax 归一化)。
专家轨迹 τexp 与模板集做 L2 最近邻 → 选出 i∗。
构造 one-hot 标签:qi∗=1。
交叉熵:Lplan=−logp(τi∗∣o)。
(可选)感知损失、分割损失(多任务 joint loss)。
多批数据迭代后,网络就学会:专家常走的区域 = 低代价;危险/非法区域 = 高代价。
成果:得到一个可解释的 BEV cost map和一个轨迹选择子网络