3D点云目标检测网络简介

https://www.cnblogs.com/xiaxuexiaoab/p/17970121
前面的文章介绍了点云目标检测的几篇综述文献,这一篇参考第二篇综述介绍一些经典的网络,主要包含其大体内容、贡献点和一些细节,后续还会慢慢补充。

=========== One Stage ============

一、VoxelNet

PDF:https://arxiv.org/abs/1711.06396
CODE:https://github.com/skyhehe123/VoxelNet-pytorch

大体内容

不同于piontNet等直接在点云上操作,VoxelNet将点云空间划分成相同大小体素格子,然后记录每个体素里面的点,对每个体素里面的点进行采样并借助多个VFE层提取出点云特征,然后通过一个中间卷积层(由于VFE输出是4维张量,所以采用的3D卷积),扩大感受野的同时进一步获得更多的特征信息,最后借助一个RPN模块,类别分支输出检测物体的类别信息,回归分支输出中心点、长宽高以及角度相对于Anchor的偏移量。

贡献点

  • 采用体素对点云进行划分,特征是相对于每个格子的
  • 提出VFE结构用于特征提取

细节

  1. 随机采样
    划分成体素格子后,由于点云密度不一致,有些格子里面点云可能比较多,对超出给定数量T的格子,需要进行随机采样,保证每个格子点不超过T个,少于T个的在实现中采用补0的方式。

  2. Voxel Feature Encoding(VFE)
    一个VFE的结构如下图所示

    特征提取采用的是多个VFE层对每个格子的点云进行特征编码。第一个VFE输入特征为每个点的(x,y,z,r,x-vx,y-vy,z-vz),其中r表示反射强度,经过一个全连接网络FCN(线性层+BN+ReLU)进行特征提取得到Point-wise Feature, 然后在不同点的特征之间进行maxpool,获得Locally Aggregated Feature(反应了这些点的一个局部关系),最后将Point-wise Feature和Locally Aggregated Feature进行了简单的堆叠融合,作为下一个VFE层的输入。最后一个VFE层之后经过maxpool操作得到这个格子的特征Voxel-wise Feature。

  3. 加速实现
    在实现上,采用Mask掩膜过滤掉格子特征全为0的情况,即没有标记的格子不参与特征提取等后续计算。

  4. RPN
    如下图所示RPN以中间卷积层的输出特征图为输入,分别经过三次下采样(每次stride=2)获得三个不同维度的特征图。最后将这个三个特征图缩放至同一维度后进行拼接。但这里采用的是2D卷积,前面提到中间层采用的是3D卷积,而后面这里能采用2D卷积是因为其将中间层输出的channel和depth两个维度用view函数merge到一起了

  5. 损失函数
    采用的损失函数如以下二式,其中pos表示正样本,neg表示负样本,第一行表示正负样本的分类损失,第二行表示和正样本的回归损失。

    回归损失包含以下七个维度,分别为中心点位置\(x,y,z\),框的长宽高\(l,w,h\)以及偏转角\(\theta\),其具体定义如式一,其中g表示真实框,a表示anchor。

二、Second

PDF:https://www.mdpi.com/1424-8220/18/10/3337
CODE:https://github.com/traveller59/second.pytorch

大体内容

SECOND(Sparsely Embedded Convolutional Detection)可以理解成VoxelNet的升级版,在VoxelNet上主要做了两点改进:第一是在把VoxelNet中间的卷积层里面的3D卷积替换成了稀疏卷积,可以提升模型的速度,第二个是修改方向损失函数,并在输出部分新增了一个方向分支,用于预测框的方向类别(二分类),可以使得模型训练时更好的收敛。

贡献点

  • 采用稀疏卷积替代3D卷积
  • 输出结果上新增方向分类,并提出朝向角度损失函数
  • 从数据库中采样的数据增强方法

细节

1. 角度分类分支
这里有个两个问题:一个是这样做的目的,还有一个是为角度分支什么是采用的分类?
在前面提到的VoxelNet中偏转角直接采用回归损失,那当预测框和真实框位置差不多,但方向趋于相反时,就会造成中心点以及长宽高的损失比较小,而角度回归的损失比较大,这样不太利于模型收敛。

SECOND中采用的办法是在回归之前先算出角度偏差的Sin值,然后再计算回归损失,那上述问题的损失就会趋于0,但是这样处理又存在一个新得问题,就是预测的方向和真实框又可能相差180度,所以在最后输出部分又新增了一个方向二分分类器,用于判断方向是否相反

2. 数据增强
从训练数据集中生成一个包含所有真实标签及关联点云数据(真实3D标签框里面的点)的数据库,在训练过程中随机选择几个物体并将关联的点引入到训练点云中,另外还添加一定的噪声以及全局旋转和缩放等操作。

3. 稀疏卷积
主要目的是用来加速模型推理过程,并且可以减少内存占用。其大体思想先像普通卷积一样先扫描一遍,构建输入输出规则索引矩阵(这里不做具体计算,只记录输入和输出索引对应的关系),在真正做卷积时就可以跳过不需要计算的0元素,计算完成后再借助索引矩阵恢复至输出相应位置。

这一个是SECOND的重点,也是比较难理解的地方,感兴趣的可以参考:how-does-sparse-convolution-work 或者 通俗易懂的解释Sparse Convolution过程
规则生成算法
通过规则矩阵,可以快速查找和计算相关的输入位置和输出位置。在稀疏卷积的计算过程中,根据规则矩阵中的对应关系,可以将输入位置和权重进行求和,得到卷积输出。

设计了一种基于GPU运行的规则生成算法

首先收集输入索引和关联的空间索引,而不是输出索引(第一个循环),得到了重复的输出位置,以及卷积核的偏移Offset;
然后对空间索引数据执行去重算法,获得输出索引及关联的空间索引,从先前的结果中生成与稀疏数据具有相同空间尺寸的缓冲区,以便在下一步中进行表查找(第二个循环);
最后,真正开始进行卷积计算,并使用存储的空间索引来获取每个输入索引对应的输出索引(第3个循环)。

举个2D的例子便于大家理解,假设输入是一个5 * 5的张量,现在只考虑一个通道,该通道只有(1,1)的值为A,(3,2)的值为B,卷积核采用3 * 3,其权重依次为K1, K2, ..., K9,则按照普通卷积其输出如下图右上角所示,记录输入输出的索引以及卷积核的偏移量(注意,这里采用的是普通稀疏卷积,没有采用Submanifold Sparse Convolutional(其区别在于普通稀疏卷积只要遇到非零元素即进行卷积运算,而Submanifold Sparse Convolutional需要求中心点非零才进行卷积运算,更多内容可以参考论文中的参考文献25,26,27))。

按照卷积的定义展开索引,可以得到左侧的索引列表,由于有些输出索引重复了,所以对其序号进行去重处理得到中间列表,最后依据卷积核对应的输入和输出序号既可以关联到输入和输出索引,进而得到规则表。

三、PointPillar

PDF: https://arxiv.org/pdf/1812.05784.pdf,
CODE: https://github.com/nutonomy/second.pytorch

大体内容

前面提到的VoxelNet及SECOND都是将点云划分成大小均匀的体素,然后对体素中的点云借助VFE层进行特征提取,虽然后续SECOND采用稀疏卷积将VoxelNet的速度从4.4HZ提升到了20HZ,但PointPillar的推理速度是62HZ。PointPillar提出将点云先转换成一个个的柱子(Pillar),然后经过Pillar Feature Net将提取的特征转换成一个伪图片,之后就可以像2D图像一样接一个BackBone和一个检测头即可,所以内部采用的是2D卷积,因而速度上快很多。

贡献点

  • 提出Pillar Feature Net将点云划分成Pillar进行处理,并将特征转换为伪图片
  • 检测速度提升至62HZ,平衡了检测速度和检测精度

细节

1、如何划分成Pillar
这个比较好理解,先将点云空间按照X轴和Y轴划分成指定大小的均匀网格,网格大小为W * H,然后每个网格在往上拉就形成了一个主体,每个柱体的特征为(D, N), D为9维特征(x,y,z,r,xc,yc,zc,xp,yp),其中(x,y,z)表示坐标,r表示反射强度,(xc,yc,zc)为点到当前柱体所有点平均值的偏移量,(xp, yp)表示每个点到柱体中心的偏移量, N表示每个柱子点最大个数

2、如何转换为2D伪图片
经过前面的柱体划分,假设有P个柱子非空(存在点云),那输入特征维度变为(D,P,N),然后采用PointNet的方式提取每个柱体的点云特征,经过BN和ReLU层后得到(C, P, N)维特征,最后对每个柱体特征进行最大池化得到[C,P]维特征,最后在将每个柱体P的位置对应回原来的2D网格位置,即可将特征转换成[C, H, W],这样就得到了2D伪图像,后续操作直接接2DBackBone和检测头(文中采用的是SSD)就可以。

3、训练过程中遇到的问题

  • 问题:ValueError: you must specify arch if use cuda.

  • 解决方法: 参考https://github.com/traveller59/second.pytorch/issues/69
    按照以下步骤生成nms.so库即可,注意修改成自己的路径

    (1) when you run:
    "g++ -std=c++11 -shared -o /home/yy/second.pytorch/second/core/non_max_suppression/nms.so ../cc/nms/nms_kernel.cu.o ../cc/nms/nms.cc -I/usr/local/cuda/include -fPIC -O3 -I/home/yy/anaconda3/include/python3.6m -I/home/yy/.conda/envs/open-mmlab/include/python3.6m -L/usr/local/cuda/lib64 -lcublas -lcudart "
    will show error "../cc/nms/nms.h:3:31: fatal error: pybind11/pybind11.h: No such file or directory"
    (2) And you need add this path to the command:" -I/home/yy/.conda/envs/open-mmlab/lib/python3.6/site-packages/pybind11/include " as follow:
    "g++ -std=c++11 -shared -o /home/yy/second.pytorch/second/core/non_max_suppression/nms.so ../cc/nms/nms_kernel.cu.o ../cc/nms/nms.cc -I/usr/local/cuda/include -fPIC -O3 -I/home/yy/anaconda3/include/python3.6m -I/home/yy/.conda/envs/open-mmlab/include/python3.6m -I/home/yy/.conda/envs/open-mmlab/lib/python3.6/site-packages/pybind11/include -L/usr/local/cuda/lib64 -lcublas -lcudart "

    (3) Then, will generate "nms.so" on "/home/yy/second.pytorch/second/core/non_max_suppression"

  • 问题:No module named 'sparseconvnet'

  • 解决方法:由于给的代码里面是基于SECOND开发的,所以需要稀疏网络库,直接pip install spconv,然后用spconv替换sparseconvnet


其他待补充

HVNet

引入注意力机制,混合不同尺度的体素特征,提升精度的同时保证速度。

TANet

引入更多级别的注意力(如通道注意力、点注意力、体素注意力)机制称为TA(Triple Attention)模块
提出CFR(coarse-to-fine regression)机制,基于粗糙回归结果,在包含有用信息的融合跨层特征图上再执行细化回归(fine regression)

PointGNN

之前都是采用voxel作数据预处理,PointGNN首次提出用graph来预处理点云数据,将数据集中的点云编码成图,并提出了Point-GNN网络,其为了减少误差设计了一个自动配准机制,为了预测的精准度,设计了一个3D目标框的融合机制,提高了算法的精准度

3DSSD

1、本文提出的3D-SSD是一个综合利率和精度的one-satge的目标检测框架。
作者这里提出观点,如果要point-based的方法提高效率,就必须要要改进或者丢掉耗时很久的上采样,因此作者的做法是设计了一种采样策略,通过下采样得到的少数点去预测detections也成为可能。
SA层相比于PointNet++,改进之处是引入了F-FPS(计算特征之间的距离),与原先采用D-FPS(位置欧式距离)各取一些用于分类和回归(只用F-FPS,回归较好,但造成前背景不均衡,分类效果下降,所以都取一些)
还引入Candidate generation layer(CG层):这一层首先要得到候选点,然后基于候选点,通过不断整合候选点周围的的语义信息。
2、作者为了实现采用point-based的方法,同时又能兼顾精度和效率,设计了candidate generation layer和anchor-free regression head以及3D center-ness assignment strategy。
3、这是一个 onestage anchor free的目标检测方法,比所有的 voxel-based的但阶段检测方法效果都要好

=========== Two Stage ============

F—PointNet

输入RGB-D data,先通过Mask R-CNN在RGB图像上找到2D region proposal,结合该区域的depth后得到frustum proposal,接着,在该frustum中使用PointNet++进行3D instance segmentation(进一步缩小proposal的三维空间),最后,利用T-Net对坐标归一,并再次使用PointNet++,回归出物体3D Bouding Box的相关参数。

Point-RCNN

第一个只用输入原始点云的两阶段3d目标检测方法

Part A^2

来自港中文和商汤合作的一篇论文,其数据预处理方式是voxel。这篇文章的主要作者和Point-RCNN作者是一个人,可以看做Point-RCNN的后续,目标都是想更好地利用box的标注信息。文章亮点是作者提出的part location和ROI-aware pooling。
对比着Faster-RCNN来进行理解,part-aware stage就相当于主干网络和RPN,它的输出就是一个4维度feature map和Proposals。Part-aggregation stage就相当于RoI Pooling和后面的Classifier的这部分

PV-RCNN

本文是一个将point_based的方法和voxel_based方法的结合的新型网络结构

  • 基于网格的方法计算效率更高,但不可避免的信息丢失会降低细粒度的定位精度
  • 而基于点的方法具有较高的计算成本,但可以通过点集抽象轻松实现更大的接收范围,并且提取存在的问题,这也是作者的论文出发点,结合这两种方法的优点。
posted @ 2024-02-11 20:04  半夜打老虎  阅读(299)  评论(0编辑  收藏  举报