paper:https://arxiv.org/abs/1711.06396
github:https://github.com/skyhehe123/VoxelNet-pytorch.git
简介
VoxelNet是一个端到端利用点云进行3D目标检测的网络,它的最大特征是把点云转成体素(voxel,所谓体素,其实就是网格,三维空间中的网格)形式再进行特征提取。
VoxelNet填补了点云特征学习和把RPN用于3D目标检测之间的鸿沟。
VoxelNet网络结构
首先将三维点云划分为一定数量的Voxel,然后进行点的随机采样以及归一化,再对每一个非空Voxel使用若干个VFE层进行局部特征提取,得到Voxel-wise Feature,然后经过3D Convolutional Middle Layers进一步抽象特征,最后使用RPN(Region Proposal Network)对物体进行分类检测与位置回归。
Feature Learning Network
Voxel Partition
体素划分:对于输入点云,使用相同尺寸的立方体对其进行划分,这里使用一个深、高、宽分别为 (D,H,W) 的大立方体表示输入点云,每个voxel的深宽高为
( v D , v H , v W ) (v_D, v_H, v_W) (vD,vH,vW),
则整个数据的三维体素化的结果在各个坐标上生成的Voxel的个数为
( D V D , H V H , W V W ) (\frac{D}{V_D},\frac{H}{V_H},\frac{W}{V_W}) (VDD,VHH,VWW);
Grouping
分组:规定同一voxel内的点进行统一处理。
Random Sampling
随机采样:为了减少不同voxel间点数量差距带来的不平衡和偏差,采取对每个voxel选取 T 个点(通过随机取样选取)进行后续处理的方法。
Stacked Voxel Feature Encoding
使用VFE层进行voxel特征编码:
- 对每个非空体素voxel
V = { p i = [ x i , y i , z i , r i ] T ∈ R 4 } i = 1... t V = \left\{p_i = [x_i, y_i, z_i, r_i]^T \in R^4\right\}_{i=1...t} V={pi=[xi,yi,zi,ri]T∈R4}i=1...t
中的每一个点进行如下操作: 计算体素中心 ( v x , v y , v z ) (v_x, v_y, v_z) (vx,vy,vz),然后强化 p i p_i pi得到新的体素
V i n = { p i = [ x i , y i , z i , r i , x i − v x , y i − v y , z i − v z ] T ∈ R 4 } i = 1... t V_{in} = \left\{p_i = [x_i, y_i, z_i, r_i, x_i - v_x, y_i-v_y, z_i-v_z]^T \in R^4\right\}_{i=1...t} Vin={pi=[xi,yi,zi,ri,xi−vx,yi−vy,zi−vz]T∈R4}i=1...t
V i n V_{in} Vin作为作为VFE-Layer层的输入,即Point-wist Input。
- Point-wist Input 通过Rule激活函数和Batch Normal运算的全连接网络,获得每一个点的特征,即Point-wist Feature。
- 对Point-wist Feature进行逐点max-pool运算,获得局部聚合特征,即Locally Aggregated Feature。
- 逐点连接Point-wise Feature和Locally Aggregated Feature,获取逐点连接特征,即Point-wise concatenated Feature。
Sparse Tensor Representation
稀疏张量表示:
通过前四个步骤的处理,可以得到一系列的Voxel Feature(只对非空Voxel进行),这些Voxel Feature可以使用一个4维的稀疏张量来表示 : C × D’ × H’ × W’ 。
稀疏张量只处理非空体素,这种表示体素特征的方法可以减少内存和计算资源。举个例子:
- 沿着lidar坐标系(Z,Y,X)方向取[-3,1]×[-40,40]×[0,70.4]立方体(单位为米)作为输入点云,取Voxel的尺寸为: v D = 0.4 , v H = 0.2 , v W = 0.2 v_D=0.4, v_H=0.2, v_W=0.2 vD=0.4,vH=0.2,vW=0.2, 那么我们就可以计算得出这里的D’=10,H’=400,W’=352。
- 设置随机采用的T=35,并且采用两个VFE层:VFE-1(7,32)和VFE-2(32,128),最后的全连接层将VFE-2的输出映射到 R 128 R^{128} R128。
- 那么最终我们的特征学习网络得到的输出即为一个尺寸为(128×10×400×352)的4D稀疏张量,其中128代表特征维度,后面是Voxel的个数。
Convolutional Middle Layers
中间卷积层:
- 经过前面的处理后点云图的特征已经变成了规则的4D tensor,然后使用3D卷积来进行特征提取,卷积中间层在逐渐扩展的感受野中聚集voxel feature,为形状描述添加更多信息。(这一层是整个网络时间开销最大的一部分)
- 每个卷积中间层包含一个3维卷积,一个BN层,一个非线性Relu层,用来描述一个3D卷积中间层, C i n C_{in} Cin代表输入的通道数; C o u t C_{out} Cout表示输出的通道数;k是卷积核的大小,对于三维卷积而言,卷积核的大小是(k ,k,k);s 表示stride ,卷积操作的步长;p即padding , 填充的尺寸。
经过FLN之后,输出变为128×10×400×352(128代表特征维度,后面是voxel的个数);
经过Conv3D(128,64,3,(2,1,1),(1,1,1)), Conv3D(64,64,3,(1,1,1),(0,1,1)), Conv3D(64,64,3,(2,1,1),(1,1,1))之后,输出变为 64×2×400×352,经过reshape,变为128×400×352。 所以输入RPN的feature map的大小就是128×400×352.
Region Proposal Network
RPN区域候选网络:
- RPN网路的输入是通过 Convolutional Middle Layers出来的特征图;
- 该网络包含三个全卷积层块(Block),每个块的第一层通过步长为2的卷积将特征图采样为一半,之后是三个步长为1的卷积层,每个卷积层都包含BN层和ReLU操作。将每一个块的输出都上采样到一个固定的尺寸并串联构造高分辨率的特征图。
- 最后,该特征图通过两种2D卷积被输出到期望的学习目标:①概率评分图(Probability Score Map)②回归图(Regression Map)。
Efficient Implementation
提效措施:
(1)第一步是初始化一个tensor,储存为 K × T × 7 的feature buffer。K表示一个有存在的非空的体素的最大值,T表示的每个voxel中点的最大值。7就是每一个点编码的特征维度。
(2)第二步是对于点云中的任意一个点去查找它所在的voxel是否初始化,如果已经初始化了那么就检查是否大于T个点,没有的话就插入进去,否则不要这个点。假如这个voxel没有被初始化,那么就需要初始化并把这个点加入进去。
(3)建立了input buffer之后呢,采用GPU的并行计算对点级别和voxel级别的VFE计算,在VFE中的concate之后,把没有点的特征再次设置为0。最后,使用存储的坐标缓冲区,将计算的稀疏体素结构重新组织到密集体素网格。
标签:voxel,Voxel,卷积,Feature,VoxelNet,128,网络结构,体素 From: https://blog.csdn.net/zfjBIT/article/details/145200475