《A Simple Baseline for BEV Perception Without LiDAR》论文笔记
参考代码:[bev 基线](https://github.com/aharley/bev 基线)
项目页面:A Simple Baseline for BEV Perception Without LiDAR
1. 概述
本文提出了一种简洁有效的bev特征提取方法。
其核心在于通过在构建的bev grid中将图像特征反向投影到该网格,并在投影点处执行双线性插值采样来获取图像模态下的bev特征。
同时,在编码层之后将lidar和radar等其他传感器的数据与现有的bev特征进行连接融合,以构建多模态的bev特征。
此外,在网络训练过程中详细探讨了batchsize、image augmentation和image resolution等超参数对模型性能的影响,并通过消融实验验证了这些因素的重要性。
实验结果表明这些数据对于提升bev感知效果具有重要意义。
该研究采用ResNet-101作为主干网络架构。
在本节中详细阐述了bev构建过程的方法论。在此基础上探讨了多种bev构建方案及其适用性分析

- 1)对网络提取金字塔特征(即不同CNN网络各层级输出的不同特征),通过网络映射实现为不同深度范围内的BEV特征映射。该方法的具体实现可参考左上角图示:pyramid.py;
- 2)将深度信息隐式编码至网络特征图中并构建视锥体(即类似于LSS方法所展示),见右上角图;
- 3)将BEV特征构建任务转化为宽度方向上的投影任务(如左下角所示);
- 4)首先构建BEV网格并以此作为Transformer的查询端(即Queries),通过注意力机制最终生成BEV特征。
2. 方法设计
2.1 pipeline
文章的方法如下:

接收多模态传感器数据后,在经过编码处理后会被统一投影到BEV(Bird's Eye View)特征求取空间中,并随后通过concat模块融合多种路径信息来构建完整的BEV特征求取空间。在此过程中优化BEV解码器时,在优化过程中,在Y轴方向上对BEV特征求取空间进行压缩投影处理以降低维度复杂度的同时提升表示能力。为了提高BEV特征求取空间的表示能力,在优化阶段采用ResNet-18网络构建一个U型结构以便于后续的精炼过程,并根据需求设置多个预测分支以完成BEV估计任务。
在构建bev特征的过程中,在采用投影之后双线性采样的形式进行处理。如图所示:

2.2 bev投影过程
这部分的核心是较为独立的空间坐标变换操作:
# utils/vox.py#291
def unproject_image_to_mem(self, rgb_camB, pixB_T_camA, camB_T_camA, Z, Y, X, assert_cube=False):
# rgb_camB is B x C x H x W camera特征
# pixB_T_camA is B x 4 x 4 到相机坐标到图像坐标——内参
# pixB_T_camA is B x 4 x 4 世界坐标到相机坐标转换——平移和旋转矩阵
# rgb lives in B pixel coords
# we want everything in A memory coords
# this puts each C-dim pixel in the rgb_camB
# along a ray in the voxelgrid
B, C, H, W = list(rgb_camB.shape)
xyz_memA = utils.basic.gridcloud3d(B, Z, Y, X, norm=False, device=pixB_T_camA.device) # 构建3D空间网格[B,N,3]
xyz_camA = self.Mem2Ref(xyz_memA, Z, Y, X, assert_cube=assert_cube) # 将3D空间点映射到图像对应相机坐标维度
xyz_camB = utils.geom.apply_4x4(camB_T_camA, xyz_camA)
z = xyz_camB[:,:,2]
xyz_pixB = utils.geom.apply_4x4(pixB_T_camA, xyz_camA) # 相机坐标3D空间点到图像特征的映射
normalizer = torch.unsqueeze(xyz_pixB[:,:,2], 2)
EPS=1e-6
# z = xyz_pixB[:,:,2]
xy_pixB = xyz_pixB[:,:,:2]/torch.clamp(normalizer, min=EPS) # 除以深度信息得到XY平面坐标
# this is B x N x 2
# this is the (floating point) pixel coordinate of each voxel
x, y = xy_pixB[:,:,0], xy_pixB[:,:,1]
# these are B x N
x_valid = (x>-0.5).bool() & (x<float(W-0.5)).bool() # 计算投影之后XY平面坐标的有效性
y_valid = (y>-0.5).bool() & (y<float(H-0.5)).bool()
z_valid = (z>0.0).bool()
valid_mem = (x_valid & y_valid & z_valid).reshape(B, 1, Z, Y, X).float()
if (0):
# handwritten version
values = torch.zeros([B, C, Z*Y*X], dtype=torch.float32)
for b in list(range(B)):
values[b] = utils.samp.bilinear_sample_single(rgb_camB[b], x_pixB[b], y_pixB[b])
else: # 实现在图像特征上双线性插值采样
# native pytorch version
y_pixB, x_pixB = utils.basic.normalize_grid2d(y, x, H, W)
# since we want a 3d output, we need 5d tensors
z_pixB = torch.zeros_like(x)
xyz_pixB = torch.stack([x_pixB, y_pixB, z_pixB], axis=2)
rgb_camB = rgb_camB.unsqueeze(2)
xyz_pixB = torch.reshape(xyz_pixB, [B, Z, Y, X, 3])
values = F.grid_sample(rgb_camB, xyz_pixB, align_corners=False)
values = torch.reshape(values, (B, C, Z, Y, X)) # raw 4D的bev特征
values = values * valid_mem
return values
2.3 影响性能的一些方面
2.3.1 数据增广
文章针对图片颜色、对比度以及模糊等数据增强操作进行了相关测试。实验结果表明,在该分类任务中这些增强方法的效果并不显著,并且可能会产生负面影响。
2.3.2 输入图像分辨率

对于分辨率并非呈现为单调线型变化关系而言,文章给出的具体解释是ResNet-101基于COCO的数据集进行了object detection方面的预训练工作,并且能够适应于该数据集所包含的目标尺寸,在此背景下,在bev任务中呈现出一定的分辨率上的先验特性。
2.3.3 batchsize

通过分析表格中的数据可以看出,在该研究中发现batchsize与性能之间存在显著的正相关关系。此外,在文章所提供的代码实现中也采用了基于梯度累加的方法来提升batchsize的效果。
# train_nuscenes.py#L405
for internal_step in range(grad_acc):
...
2.3.4 reference camera和camera nums对性能的影响

通过查看表格数据表明reference camera转换会带来增长点,并且采用全面的camera方案同样能获得增长
2.3.5 radar超参数带来的影响

3. 实验结果
vehicle segmentation on nuScenes:

时序与传感器数据类型对性能的影响:

