盘一盘 | 基于BEV空间的视觉感知算法模型梳理(自下而上&自上而下)(上)

本文涉及的产品
交互式建模 PAI-DSW,每月250计算时 3个月
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
模型训练 PAI-DLC,5000CU*H 3个月
简介: 激光雷达传感器可以提供物体准确的深度信息以及结构信息;但激光雷达传感器提供物体信息的距离比较有限,同时其获得的点云数据与相机传感器采集到的图像信息相比更加稀疏;

一、基于BEV空间的自动驾驶感知任务



最近,基于BEV空间下的感知任务已经涌现出了众多优秀算法,并在多个自动驾驶公开数据集(KITTI,Waymo,nuScenes)上取得了非常不错的成绩。根据自动驾驶汽车上安装的传感器类型(视觉传感器:针孔/鱼眼相机传感器、激光雷达传感器、毫米波雷达传感器)对感知算法进行分类的话,可以大致分为以下三个类别:


  • 基于纯视觉/图像信息构建BEV空间特征实现自动驾驶感知任务
  • 基于纯激光雷达信息构建BEV空间特征实现自动驾驶感知任务
  • 基于多种传感器信息融合构建BEV空间特征实现自动驾驶感知任务


在这里,简单总结下不同传感器的优缺点,正是由于各个传感器之间可以取长补短,所以目前的自动驾驶汽车上通常都会配备不同类型的传感器。


  • 激光雷达传感器(Lidar)
    激光雷达传感器可以提供物体准确的深度信息以及结构信息;但激光雷达传感器提供物体信息的距离比较有限,同时其获得的点云数据与相机传感器采集到的图像信息相比更加稀疏;

  • 相机传感器(Camera)
    相机传感器可以很好的捕捉图像中物体包含的丰富的色彩和纹理信息;但由于图像成像过程中的限制,得到的2D图像无法保留物体在深度方向的信息;

  • 毫米波雷达传感器(Radar)
    毫米波雷达传感器采集到的数据相比于激光雷达传感器获取的数据更加稀疏;但其获取的物体信息范围相较于激光雷达传感器更远,同时可以更好的采集运动物体的信息;


虽然激光雷达传感器可以提供自动驾驶感知任务中不可或缺的深度信息,但是给汽车配备一套激光雷达设备的价格远高于给汽车配备一套相机设备的价格。所以,近年来涌现出诸多基于纯视觉的自动驾驶感知算法。而本文也主要是对基于纯视觉的感知算法模型进行梳理。


在完成后续算法模型梳理之前,先简单概括下基于BEV空间实现感知任务所具有的一些优势。


二、基于BEV空间实现感知任务的优势



  • 在各类算法模型得到BEV空间特征后,可以基于获得的BEV特征实现3D目标检测、车道线检测、地图语义分割等不同的感知任务,而且不同任务的感知结果可以很自然的应用到自动驾驶的后续模块(如:规划和控制);

  • 在BEV空间下,可以非常方便的将不同视角、不同时间序列(帧)、不同模态(传感器)的特征信息进行融合,输出更加准确的BEV空间特征,从而更好地实现自动驾驶感知任务;

  • 相较于基于Perpective View的纯视觉感知方法,基于BEV空间的感知算法以俯视的角度去实现感知任务,可以比较好的缓解不同物体间的遮挡问题;


既然基于BEV空间实现感知任务具有诸多优势,同时纯视觉的方法造价又相对低廉,所以基于BEV空间下的纯视觉感知算法应运而生。但正如前文所提到的,激光雷达设备虽然造价高昂,但是却可以为自动驾驶感知任务提供物体在深度方向上的准确的信息。而纯视觉的自动驾驶感知算法由于只利用了2D图像的特征,没有深度方向的信息可以利用,所以如何基于2D的图像特征去实现BEV空间特征的构建成为了这类方法的核心问题。笔者这里根据当下比较主流的构建方式划分为两大类:


  • 第一大类:自下而上的BEV空间特征构建方法(也被称为基于深度的方法)
    这类方法大体的思路是利用人工设计的深度预测网络对图像像素的深度信息进行预测,进而实现将网络提取到的2D图像特征转换为3D的相机视锥特征,实现2D空间特征到3D空间特征的转换,然后,再利用后续的Voxel Pooling等操作实现BEV空间特征的构建。

  • 第二大类:自上而下的BEV空间特征构建方法
    这类方法大体的思路是先在BEV空间下,根据点云的感知范围以及体素大小预先构建一组3D空间网格,然后利用相机内外参变换矩阵将3D空间网格点投影到图像坐标系下,接着对相应位置处的二维图像特征(通常为环视图像特征)进行采样,最终实现BEV空间特征的构建。或者利用最近比较火的Transformer中的的Query思想,在3D空间下初始一组Object Query,通过Cross-Attention的思想将Object Query与图像特征进行交互,得到BEV特征从而预测感知结果。

三、自下而上的BEV空间特征构建方法



自下而上的感知算法如前文所说,主要利用深度预测网络预测出图像像素的离散深度信息,实现2D图像特征向3D空间特征的转换,下面主要梳理下比较经典的LSS和BEVDet算法模型。


1. LSS:Lift, Splat, Shoot: Encoding Images From Arbitrary Camera Rigs by Implicitly Unprojecting to 3D


论文链接:https://arxiv.org/pdf/2008.05711.pdf

Github仓库源码:https://github.com/nv-tlabs/lift-splat-shoot

LSS是发表在ECCV 2020上的一篇论文,其主要是解决感知中的地图分割任务的,但其利用深度估计网络预测像素的离散深度,从而利用2D图像特征构建3D特征的思想被大多数感知算法借鉴。LSS算法模型的整体流程图如下:

640.png


LSS算法模型的前向过程主要包括以下五个部分:


  • 构建相机视锥坐标下的3D空间网格,并利用相机的内外参变换矩阵将3D空间网格点投影到到BEV空间下;
  • 利用主干网络和特征融合网络提取输入环视图片的2D图像特征;
  • 利用深度估计网络预测特征图中每个单元格的语义信息和深度概率分布,通过外积运算构建相机视锥特征;
  • 对投影到BEV空间下的坐标点以及相机视锥特征,利用体素池化(Voxel Pooling)构建BEV空间特征;
  • 对输出的BEV特征利用BEV Encoder模块完成多尺度特征的提取和融合,将融合后的特征用于完成地图分割任务;

构建相机视锥下的3D网格 + 空间点投影到BEV空间


  • 构建相机视锥下的3D网格(源码中的creat_frustum()函数)
Python
def create_frustum():
    ogfH, ogfW = self.data_aug_conf['final_dim']  # 原始图片大小  ogfH:128  ogfW:352
    fH, fW = ogfH // self.downsample, ogfW // self.downsample  # 下采样16倍后图像大小  fH: 8  fW: 22
    # self.grid_conf['dbound'] = [4, 45, 1]  # 在深度方向上划分网格 ds: DxfHxfW (41x8x22)
    ds = torch.arange(*self.grid_conf['dbound'], dtype=torch.float).view(-1, 1, 1).expand(-1, fH, fW)
    D, _, _ = ds.shape # D: 41 表示深度方向上网格的数量
    # 在0到351上划分22个格子 xs: DxfHxfW(41x8x22)
    xs = torch.linspace(0, ogfW - 1, fW, dtype=torch.float).view(1, 1, fW).expand(D, fH, fW)  
    # 在0到127上划分8个格子 ys: DxfHxfW(41x8x22)
    ys = torch.linspace(0, ogfH - 1, fH, dtype=torch.float).view(1, fH, 1).expand(D, fH, fW)  
    # D x H x W x 3
    # 堆积起来形成网格坐标, frustum[i,j,k,0]就是(i,j)位置,深度为k的像素的宽度方向上的栅格坐标   frustum: DxfHxfWx3
    frustum = torch.stack((xs, ys, ds), -1)  
    return nn.Parameter(frustum, requires_grad=False)

  • 利用相机内外参将相机视锥下的3D网格投影到BEV空间(源码中的get_geometry()函数)
Python
def get_geometry(self, rots, trans, intrins, post_rots, post_trans):
    B, N, _ = trans.shape  # B: batch size N:环视相机个数
    # undo post-transformation
    # B x N x D x H x W x 3
    points = self.frustum - post_trans.view(B, N, 1, 1, 1, 3)
    points = torch.inverse(post_rots).view(B, N, 1, 1, 1, 3, 3).matmul(points.unsqueeze(-1)
    points = torch.cat((points[:, :, :, :, :, :2] * points[:, :, :, :, :, 2:3],
                        points[:, :, :, :, :, 2:3]
                        ), 5) 
    combine = rots.matmul(torch.inverse(intrins))
    points = combine.view(B, N, 1, 1, 1, 3, 3).matmul(points).squeeze(-1)
    points += trans.view(B, N, 1, 1, 1, 3)
    # (bs, N, depth, H, W, 3)
    return points


利用主干网络和特征融合网络提取环视图像的2D图像特征


其中LSS原论文中采用的主干网络是EfficientNet-B0,其输出的多尺度特征如下

Python
level0 = Tensor([bs * N, 16, H / 2, W / 2])
level1 = Tensor([bs * N, 24, H / 4, W / 4])
level2 = Tensor([bs * N, 40, H / 8, W / 8])
level3 = Tensor([bs * N, 112, H / 16, W / 16])
level4 = Tensor([bs * N, 320, H / 32, W / 32])


对提取后的多尺度特征利用特征融合网络实现不同尺度特征的融合

Python
Step1: 对最后一层特征升采样到倒数第二层大小
level4 -> Up -> level4' = (bs * N, 320, H / 16, W / 16)
Step2:对主干网络输出的后两层特征进行concat
cat(level4', level3) -> output = (bs * N, 432, H / 16, W / 16)
Step3:对concat后的特征,利用卷积层进一步拟合
ConvLayer(output) -> output' = (bs * N, 512, H / 16, W / 16)
其中ConvLayer = 
"""Sequential(
  (0): Conv2d(432, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (2): ReLU(inplace=True)
  (3): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (4): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (5): ReLU(inplace=True)
)"""


利用深度估计网络预测特征图中每个单元格的语义信息和深度概率分布,通过外积运算

构建相机视锥特征


这一部分是LSS算法的核心:其主要思想是设计了一个深度估计网络对特征图每个单元格的语义信息(通道维度)和深度信息(深度方向的概率分布)进行预测,通过外积运算的方式,将2D的图像特征投影到3D的视锥特征,从而完成2D特征到3D特征的视角转换。


2D到3D部分的转换实现逻辑如下图所示(其中α ,c分别代表深度估计网络预测出来的深度概率密度以及语义特征信息);


640.png


利用体素池化根据BEV空间下的坐标点以及视锥特征构建BEV空间特征


这里在原始论文中主要采用了quick sum的方式计算BEV特征,其实现逻辑的图例如下(图例来自https://zhuanlan.zhihu.com/p/567880155


640.png


对输出的BEV特征利用BEV Encoder模块完成多尺度特征的提取和融合,融合后的特征用于完成地图分割任务;


BEV Encoder提取BEV特征后输出的多尺度特征如下

Python
level0:Tensor([bs, 64, 100, 100])
level1: Tensor([bs, 128, 50, 50])
level2: Tensor([bs, 256, 25, 25])


对输出的多尺度特征进行融合,得到最终的BEV特征,完成最后的地图分割任务

Python
Step1: level2 -> Up (4x) -> level2' = (bs, 256, 100, 100)
Step2: concat(level2', level0) -> output = (bs, 320, 100, 100)
Step3: Conv1(output) -> output' = (bs, 256, 100, 100)
''' Conv1
Sequential(
  (0): Conv2d(320, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (2): ReLU(inplace=True)
  (3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (4): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (5): ReLU(inplace=True)
)'''
Step4: Up2(output') -> final = (bs, 1, 200, 200)
'''Sequential(
  (0): Upsample(scale_factor=2.0, mode=bilinear)
  (1): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (3): ReLU(inplace=True)
  (4): Conv2d(128, 1, kernel_size=(1, 1), stride=(1, 1))
)'''


2. BEVDet: High-Performance Multi-Camera 3D Object Detection in Bird-Eye-View


论文链接:https://arxiv.org/pdf/2112.11790.pdf

Github仓库源码:https://github.com/HuangJunJie2017/BEVDet

BEVDet这篇论文主要是提出了一种基于BEV空间下的3D目标检测范式,BEVDet算法模型的整体流程图如下:


640.png


BEVDet算法模型的前向过程主要包括以下五个部分:


  • 利用主干网络和特征融合网络提取输入环视图片的图像特征(对应上图中的Image-View Encoder模块);
  • 借鉴LSS算法的思想将提取到的2D图像特征变换为3D相机视锥空间特征(对应上图中的View Transformer模块);
  • 利用体素池化根据相机视锥特征和映射后的3D相机视锥空间构建BEV空间特征(对应上图中的View Transformer模块);
  • 利用BEV Encoder模块对输出的BEV空间特征实现多尺度特征的提取和融合,得到增强的BEV特征(对应上图中的BEV Encoder模块);
  • 对增强的BEV特征接3D检测头实现3D检测任务(对应上图中的3D Object Detection Head模块);

Image-View Encoder模块:利用主干网络和特征融合网络对环视图像进行提取

论文中利用ResNet-50主干网络提取输入环视图片的多尺度特征,输出多尺度特征如下:


Python
l0 = Tensor([bs * N, 1024, H / 16, W / 16])
l1 = Tensor([bs * N, 2048, H / 32, W / 32])


利用特征融合网络对提取出来的多尺度特征进行融合

Python
Step1:分别对输出的两个尺度的特征利用Conv1x1卷积降通道
l0 -> Conv1x1 -> l0_ = Tensor([bs * N, 512, H / 16, W / 16]);
l1 -> Conv1x1_ -> l1_ = Tensor([bs * N, 512, H / 32, W / 32]);
Step2: 将降采样后的特征图进行element-wise融合
Up(l1_) + l0_ = Tensor([bs * N, 512, H / 16, W / 16]);
Step3:融合后的特征利用Conv3x3完成进一步拟合,最后输出特征为Tensor([bs * N, 512, H / 16, W / 16])


View Transformer模块:根据得到的相机视锥特征及映射后的3D坐标点利用体素池化构建BEV空间特征


View Transformer模块的逻辑与LSS论文中构建相机视锥特征、3D坐标点的投影转换以及体素池化的逻辑基本一致,用于获得BEV空间特征。这里就不再展开介绍啦。

BEV Encoder模块:对View Transformer模块输出的BEV空间特征实现多尺度特征的提取和融合,增强BEV特征表达


BEV主干网络用于实现BEV空间特征的多尺度特征提取,输出多尺度特征如下:

Python
la = Tensor([bs, 160, 64, 64]);
lb = Tensor([bs, 320, 32, 32]);
lc = Tensor([bs, 640, 16, 16]);

BEV特征融合网络用于对多尺度BEV特征进行融合,实现逻辑如下:

Python
Step1. 对lc特征进行上采样到la大小 
Tensor([bs, 640, 16, 16]) -- Up --> Tensor([bs, 640, 64, 64]);
Step2. 将la特征与lc特征进行concat,并利用Conv1x1卷积降维
Tensor([bs, 800, 64, 64]) -- Conv1x1 --> Tensor([bs, 512, 64, 64]);
Step3. 降维后的特征利用Up进行升采样,最后输出的BEV特征为Tensor([bs, 512, 128, 128])


对增强的BEV特征接3D检测头实现3D检测任务


需要注意的是,BEVDet对不同的检测类别会设置有独立的检测头,每组独立的检测头都会有六个分支来预测物体的不同属性,具体信息如下


  • reg分支:用于预测BEV下物体相对于每个单元格左上角的xy偏移量;
  • height分支:用于预测物体的高度信息;
  • dim分支:用于预测物体的尺寸大小信息;
  • rot分支:用于预测物体偏航角的正、余弦值;
  • vel分支:用于预测物体沿xy方向的速度;
  • heatmap分支:用于预测不同物体的类别概率;


原文首发微信公众号【自动驾驶之心】:一个专注自动驾驶与AI的社区(https://mp.weixin.qq.com/s/NK-0tfm_5KxmOfFHpK5mBA

相关文章
|
7天前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
24 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
7天前
|
机器学习/深度学习 人工智能 算法
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
蔬菜识别系统,本系统使用Python作为主要编程语言,通过收集了8种常见的蔬菜图像数据集('土豆', '大白菜', '大葱', '莲藕', '菠菜', '西红柿', '韭菜', '黄瓜'),然后基于TensorFlow搭建卷积神经网络算法模型,通过多轮迭代训练最后得到一个识别精度较高的模型文件。在使用Django开发web网页端操作界面,实现用户上传一张蔬菜图片识别其名称。
42 0
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
|
18天前
|
机器学习/深度学习 人工智能 算法
青否数字人声音克隆算法升级,16个超真实直播声音模型免费送!
青否数字人的声音克隆算法全面升级,能够完美克隆真人的音调、语速、情感和呼吸。提供16种超真实的直播声音模型,支持3大AI直播类型和6大核心AIGC技术,60秒快速开播,助力商家轻松赚钱。AI讲品、互动和售卖功能强大,支持多平台直播,确保每场直播话术不重复,智能互动和真实感十足。新手小白也能轻松上手,有效规避违规风险。
|
20天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
24天前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
71 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
2月前
|
机器学习/深度学习 人工智能 算法
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
鸟类识别系统。本系统采用Python作为主要开发语言,通过使用加利福利亚大学开源的200种鸟类图像作为数据集。使用TensorFlow搭建ResNet50卷积神经网络算法模型,然后进行模型的迭代训练,得到一个识别精度较高的模型,然后在保存为本地的H5格式文件。在使用Django开发Web网页端操作界面,实现用户上传一张鸟类图像,识别其名称。
108 12
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
|
1月前
|
机器学习/深度学习 数据采集 算法
如何在一夜之间成为模型微调大师?——从零开始的深度学习修炼之旅,让你的算法功力飙升!
【10月更文挑战第5天】在机器学习领域,预训练模型具有强大的泛化能力,但直接使用可能效果不佳,尤其在特定任务上。此时,模型微调显得尤为重要。本文通过图像分类任务,详细介绍如何利用PyTorch对ResNet-50模型进行微调,包括环境搭建、数据预处理、模型加载与训练等步骤,并提供完整Python代码。通过调整超参数和采用早停策略等技巧,可进一步优化模型性能。适合初学者快速上手模型微调。
92 8
|
1月前
|
机器学习/深度学习 算法 搜索推荐
django调用矩阵分解推荐算法模型做推荐系统
django调用矩阵分解推荐算法模型做推荐系统
27 4
|
2月前
|
算法
基于SIR模型的疫情发展趋势预测算法matlab仿真
该程序基于SIR模型预测疫情发展趋势,通过MATLAB 2022a版实现病例增长拟合分析,比较疫情防控力度。使用SIR微分方程模型拟合疫情发展过程,优化参数并求解微分方程组以预测易感者(S)、感染者(I)和移除者(R)的数量变化。![]该模型将总人群分为S、I、R三部分,通过解析或数值求解微分方程组预测疫情趋势。
|
2月前
|
机器学习/深度学习 数据采集 存储
一文读懂蒙特卡洛算法:从概率模拟到机器学习模型优化的全方位解析
蒙特卡洛方法起源于1945年科学家斯坦尼斯劳·乌拉姆对纸牌游戏中概率问题的思考,与约翰·冯·诺依曼共同奠定了该方法的理论基础。该方法通过模拟大量随机场景来近似复杂问题的解,因命名灵感源自蒙特卡洛赌场。如今,蒙特卡洛方法广泛应用于机器学习领域,尤其在超参数调优、贝叶斯滤波等方面表现出色。通过随机采样超参数空间,蒙特卡洛方法能够高效地找到优质组合,适用于处理高维度、非线性问题。本文通过实例展示了蒙特卡洛方法在估算圆周率π和优化机器学习模型中的应用,并对比了其与网格搜索方法的性能。
303 1

热门文章

最新文章