三维点云语义分割模型总结

  • 1.PointNet(CVPR2017)
  • 1.1 网络基本架构功能介绍
  • 1.2 网络的两个亮点:
  • 1.3 解决问题详细方案
  • 1.4 实验结果和网络的鲁棒性
  • 1.5 pointnet代码详解
  • 2.PointNet ++(NIPS 2017)
  • 2.1 网络基本架构功能介绍:
  • 2.2 网络的亮点:
  • 2.3 解决问题详细方案
  • 2.4 PointNet++代码解析
  • 3. PointSIFT
  • 4. Exploring Spatial Context for 3D Semantic Segmentation of Point Clouds(探索三维语义分割的空间信息)
  • 4.1 基础知识
  • 4.2 两种扩展模型
  • 4.2.2 GB-RCU(Grid Blocks + Recurrent Consolidation Units)
  • 5.PointCNN:可以处理点云的CNN (NIPS 2018)
  • 5.1 解决的问题
  • 5.2 算法


1.PointNet(CVPR2017)

1.1 网络基本架构功能介绍

PointNet作为直接处理点云的开拓工作,来自斯坦福大学,本文对ModelNet40数据集的准确率高达89.2%。下图是pointNet点云分类的框架:

点云道路语义分割 点云语义分割算法_点云


点云道路语义分割 点云语义分割算法_点云_02


具体来说,对于每一个N×3的点云输入,网络先通过一个T-Net将其在空间上对齐(旋转到正面),第一层卷积核大小是1x3(因为每个点的维度是xyz),之后的每一层卷积核大小都是1x1,再通过MLP(共享权重的卷积)将其映射到64维的空间上,再进行对齐,最后映射到1024维的空间上。这时对于每一个点,都有一个1024维的向量表征,而这样的向量表征对于一个3维的点云明显是冗余的,因此这个时候引入最大池化操作,将1024维所有通道上都只保留最大的那一个,这样得到的1×1024的向量就是N个点云的全局特征。

如果做的是分类的问题,直接将这个全局特征再进过MLP去输出每一类的概率即可;但如果是分割问题,由于需要输出的是逐点的类别,因此其将全局特征拼接在了点云64维的逐点特征上,最后通过MLP,输出逐点的分类概率。

1.2 网络的两个亮点:

1.空间变换网络解决旋转问题:三维的STN可以通过学习点云本身的位姿信息学习到一个最有利于网络进行分类或分割的DxD旋转矩阵(D代表特征维度,pointnet中D采用3和64)。至于其中的原理,我的理解是,通过控制最后的loss来对变换矩阵进行调整,pointnet并不关心最后真正做了什么变换,只要有利于最后的结果都可以。pointnet采用了两次STN,第一次input transform是对空间中点云进行调整,直观上理解是旋转出一个更有利于分类或分割的角度,比如把物体转到正面;第二次feature transform是对提取出的64维特征进行对齐,即在特征层面对点云进行变换。

2.maxpooling解决无序性问题:网络对每个点进行了一定程度的特征提取之后,maxpooling可以对点云的整体提取出global feature。

1.3 解决问题详细方案

1.3.1基于点云的置换不变性

简单地说就是点的排序不影响物体的性质。点云本质上是一长串点(nx3矩阵,其中n是点数)。在几何上,点的顺序不影响它在空间中对整体形状的表示,例如,相同的点云可以由两个完全不同的矩阵表示。当一个N×D在N的维度上随意的打乱之后,其表述的其实是同一个物体。因此针对点云的置换不变性,其设计的网络必须是一个对称的函数,比如SUM和MAX函数。

点云道路语义分割 点云语义分割算法_卷积_03

点云道路语义分割 点云语义分割算法_算法_04


当一个N×D在N的维度上随意的打乱之后,其表述的其实是同一个物体。因此针对点云的置换不变性,其设计的网络必须是一个对称的函数,我们经常看到的SUM和MAX等函数其实都是对称函数,此处使用了max函数设计一个简单的点云网络。

点云道路语义分割 点云语义分割算法_算法_05


这样的网络有一个问题,就是每个点损失的特征太多了,输出的全局特征仅仅继承了三个坐标轴上最大的那个特征,因此我们不妨先将点云上的每一个点映射到一个高维的空间(例如1024维),目的是使得再次做MAX操作,损失的信息不会那么多。

点云道路语义分割 点云语义分割算法_算法_06


当我们将点云的每个点先映射到一个冗余的高维空间后,再去进行max的对称函数操作,损失的特征就没那么多了。由此,就可以设计出这PointNet的雏形,称之为PointNet(vanilla):

点云道路语义分割 点云语义分割算法_算法_07


总结任意一个在Hausdorff空间上连续的函数,都可以被这样的PointNet(vanilla)无限的逼近。

点云道路语义分割 点云语义分割算法_点云_08


1.3.2 基于点云的旋转不变性

点云的旋转不变性指的是,给予一个点云一个旋转,所有的x,y,zx,y,z坐标都变了,但是代表的还是同一个物体。

点云道路语义分割 点云语义分割算法_算法_09


对于普通的PointNet(vanilla),如果先后输入同一个但是经过不同旋转角度的物体,它可能不能很好地将其识别出来。在论文中的方法是新引入了一个T-Net网络去学习点云的旋转,将物体校准,剩下来的PointNet(vanilla)只需要对校准后的物体进行分类或者分割即可。

点云道路语义分割 点云语义分割算法_特征提取_10


由图可以看出,由于点云的旋转非常的简单,只需要对一个N×D的点云矩阵乘以一个D×D的旋转矩阵即可,因此对输入点云学习3×3的矩阵,即可将其矫正;同样的将点云映射到K维的冗余空间后,再对K维的点云特征做一次校对,只不过这次校对需要引入一个正则化惩罚项,希望其尽可能接近于一个正交矩阵。

点云道路语义分割 点云语义分割算法_点云道路语义分割_11

1.4 实验结果和网络的鲁棒性

pointnet当时不论是分割还是分类的结果都超过了当时的体素系列网络,同时由于参数少等特点,训练快,属于轻量级网络。

点云道路语义分割 点云语义分割算法_卷积_12

1.5 pointnet代码详解

点云道路语义分割 点云语义分割算法_点云道路语义分割_13


点云道路语义分割 点云语义分割算法_特征提取_14


点云道路语义分割 点云语义分割算法_特征提取_15


点云道路语义分割 点云语义分割算法_算法_16


点云道路语义分割 点云语义分割算法_点云_17

2.PointNet ++(NIPS 2017)

2.1 网络基本架构功能介绍:

PointNet只是简单的将所有点连接起来,只考虑了全局特征,但丢失了每个点的局部信息。PointNet对于场景的分割效果十分一般,由于其网络直接暴力地将所有的点最大池化为了一个全局特征,因此局部点与点之间的联系并没有被网络学习到。在分类和物体的Part Segmentation中,这样的问题还可以通过中心化物体的坐标轴部分地解决,但在场景分割中,这就导致效果十分一般了。下面是Pointnet++ 架构。

点云道路语义分割 点云语义分割算法_算法_18


它本质上是PointNet的分层版本。每个图层都有三个子阶段:采样,分组和PointNeting。在第一阶段,选择质心,在第二阶段,把他们周围的邻近点(在给定的半径内)创建多个子点云。然后他们将它们给到一个PointNet网络,并获得这些子点云的更高维表示。然后,他们重复这个过程(样本质心,找到他们的邻居和Pointnet的更高阶的表示,以获得更高维表示)。使用这些网络层中的3个。还测试了不同层级的一些不同聚合方法,以克服采样密度的差异(对于大多数传感器来说这是一个大问题,当物体接近时密集样本,远处时稀疏)。他们在原型PointNet上进行了改进,在ModelNet40上的准确率达到了90.7%。

2.2 网络的亮点:

1.改进特征提取方法:pointnet++使用了分层抽取特征的思想,把每一次叫做set abstraction。分为三部分:采样层、分组层、特征提取层。首先来看采样层,为了从稠密的点云中抽取出一些相对较为重要的中心点,采用FPS(farthest point sampling)最远点采样法,这些点并不一定具有语义信息。当然也可以随机采样;然后是分组层,在上一层提取出的中心点的某个范围内寻找最近个k近邻点组成patch;特征提取层是将这k个点通过小型pointnet网络进行卷积和pooling得到的特征作为此中心点的特征,再送入下一个分层继续。这样每一层得到的中心点都是上一层中心点的子集,并且随着层数加深,中心点的个数越来越少,但是每一个中心点包含的信息越来越多。

2.解决点云密度不同问题:由于采集时会出现采样密度不均的问题,所以通过固定范围选取的固定个数的近邻点是不合适的。pointnet++提出了两个解决方案。

点云道路语义分割 点云语义分割算法_算法_19


方案一:多尺度分组;如上图左所示,比较直观的思想是,在每一个分组层都通过多个尺度来确定每一个中心点的邻域范围,并经过pointnet提取特征之后将多个特征联合起来,得到一个多尺度的新特征。

方案二:多分辨率分组;对于每一个中心点都需要多个patch的选取与卷积,计算开销很大,所以pointnet++提出了多分辨率分组法解决这个问题。如上图右所示,类似的,新特征通过两部分连接起来。左边特征向量是通过一个set abstraction后得到的,右边特征向量是直接对当前patch中所有点进行pointnet卷积得到。并且,当点云密度不均时,可以通过判断当前patch的密度对左右两个特征向量给予不同权重。例如,当patch中密度很小,左边向量得到的信息就没有对所有patch中点提取的特征可信度更高,于是将右特征向量的权重提高。以此达到减少计算量的同时解决密度问题。

2.3 解决问题详细方案

作者在第二代PointNet中主要借鉴了CNN的多层感受野的思想。CNN通过分层不断地使用卷积核扫描图像上的像素并做内积,使得越到后面的特征图感受野越大,同时每个像素包含的信息也越多。而PointNet++就是仿照了这样的结构,具体如下:

点云道路语义分割 点云语义分割算法_特征提取_20


其先通过在整个点云的局部采样并划一个范围,将里面的点作为局部的特征,用PointNet进行一次特征的提取。因此,通过了多次这样的操作以后,原本的点的个数变得越来越少,而每个点都是有上一层更多的点通过PointNet提取出来的局部特征,也就是每个点包含的信息变多了。文章将这样的一个层成为Set Abstraction。

点云道路语义分割 点云语义分割算法_点云道路语义分割_21


一个Set Abstraction主要由三部分组成:

Sampling:利用FPS(最远点采样)随机采样点

Grouping:利用Ball Query划一个R为半径的圈,将每个圈里面的点云作为一簇

PointNet: 对Sampling+Grouping以后的点云进行局部的全局特征提取;2.3.1 分类网络

分类网络只要通过这样逐层的提取局部特征,最后总结出全局特征就可以输出分类结果了,如图:

点云道路语义分割 点云语义分割算法_特征提取_22


2.3.2 分割网络

分割网络相比而言较为复杂,其会先将点云提取一个全局的特征,再通过这个全局的特征逐步上采样,大致的流程如下:

点云道路语义分割 点云语义分割算法_点云道路语义分割_23


作者在论文中讨论了上采样的一些方法,当然最简单的就是简单的广播复制Broadcasting,但其没法处理一些范围内冲突的点,论文中作者采用的是线性差值的方法,具体的公式如下:

点云道路语义分割 点云语义分割算法_卷积_24


简单来说就是距离越远的点权重越小,最后对于每一个点的权重再做一个全局的归一化。最后分割网络的结构长成这个样子:

点云道路语义分割 点云语义分割算法_卷积_25


需要注意的是,与图像分割网络U-Net类似,对于相同的点个数的层,作者采用了直连的方式将Encoder里面的特征拼接到了Decoder的特征后。

2.3.3 采样方法的创新

通过上述方法实现的PointNet++虽然在点云上的分类和分割效果有了一定的提升,但是作者发现,其在点云的缺失鲁邦性上似乎变得更差了。其原因是因为激光收集点云的时候总是在近的地方密集,在远的地方稀疏,因此当Sampling和Grouping的操作在稀疏的地方进行的时候,一个点可能代表了很多很多的局部特征,因此一旦缺失,网络的性能就会极大的受影响。从这张图可以看出,当点云的个数缺失到20%的时候,PointNet++的性能甚至还不如PointNet。

点云道路语义分割 点云语义分割算法_点云道路语义分割_26


作者对其的改进是通过引入了不同分辨率/尺度的Grouping去对局部做PointNet求局部的全局特征,最后再将不同尺度的特征拼接起来;同时也通过在训练的时候随机删除一部分的点来增加模型的缺失鲁棒性。

点云道路语义分割 点云语义分割算法_特征提取_27


最终结果如下,可以发现新的PointNet++在点缺失到80%左右都具有良好的表现:

点云道路语义分割 点云语义分割算法_点云_28

2.4 PointNet++代码解析

整体网络结构:

点云道路语义分割 点云语义分割算法_算法_29


特征提取pointnet_sa_module:

点云道路语义分割 点云语义分割算法_点云道路语义分割_30


点云道路语义分割 点云语义分割算法_点云_31


点云道路语义分割 点云语义分割算法_算法_32

3. PointSIFT

为了使模型更好地捕获形状模式,需要编码在不同方向上的形状信息。PointSIFT类比SIFT算法提出了方向编码卷积这一方法:对于一个给定点p,以它为中心的8个卦限代表了8个不同的方向。在每个卦限中,PointSIFT都在搜索半径r内搜索最近的点,以这个最近的点的特征f代表这个卦限。为了捕捉8个方向的特征,PointSIFT进行了3次方向编码卷积,在卷积后每个点的特征都以一个d维的向量来表征。方向编码卷积的示意图如图所示

点云道路语义分割 点云语义分割算法_算法_33


其网络架构如下图:

点云道路语义分割 点云语义分割算法_点云_34


点云道路语义分割 点云语义分割算法_点云道路语义分割_35


左:SA(set abstraction)moudle 和右:FP(feature propagation) moudle

PointSIFT网络的输入是原始点云数据(n x 3),对于语义分割任务,输出是每一个在各个类别上的得分(n x m)。

如图所示,PointSIFT网络分为两大部分,分别是编码(下采样)和解码(上采样)。PointSIFT首先先通过一个MLP提取点云数据的特征(实际模型中这部分MLP和PointSIFT结合起来了),对每个点都得到一个64维的特征向量(n x 64),然后利用PointNet++的SA module进行了3次下采样,点的数量变化:8192->1024->256->64。对于解码部分,PointSIFT同样利用PointNet++中的FP module进行了3次上采样,点的数量变化:64->256->1024->8192。并且在上采样和下采样的过程中,PointSIFT module是插入在上下两个解码(编码)层之间的。模型的最后接了全连接层,得到每个点的类别得分。

在实验中,通过将PointSIFT module插到两个SA之间可以捕捉到所有的点,从而有效的避免在下采样过程中点的信息损失。

4. Exploring Spatial Context for 3D Semantic Segmentation of Point Clouds(探索三维语义分割的空间信息)

在本文中,作者在PointNet的基础上提出了两种扩展模型,增大了模型在3D场景中的感受野,从而使模型可以处理更大尺度的空间场景。

4.1 基础知识

4.1.1 Input-Level Context 输入级别的信息

Input-level context是直接对输入的点云进行处理,通过同时考虑一系列Block而不是像PointNet中考虑一个个单独的Block,一组中的Block之间共享上下文信息。Block有两种选取方式,一种是在位置相同,但是尺度不同(Multi-Scale Blocks);另一种是从相邻的格网中选取(Grid Blocks)。

1)Multi-Scale Blocks。通过随机选取一个D维的点作为中心,然后在中心点特定半径内选取N个点,将它们组合成一个Block。通过改变不同的半径从而得到Multi-Scale Blocks,Multi-Scale Blocks如图所示。

点云道路语义分割 点云语义分割算法_卷积_36


2)Grid Blocks。Grid blocks是一组2 x 2的格网领域。每个Block位置不同但是尺度相同,如图所示:

点云道路语义分割 点云语义分割算法_点云_37


4.1.2 Consolidation Units(CU)合并单元

CU和RCU均是处理Output-level context,它们将合并得到的块特征。先是CU的处理方式:CU先通过MLP将之前阶段得到的特征集映射到更高维的空间,然后应用max-pooling生成公共块特征,然后将该特征与MLP得到的O个高维特征进行连接。

点云道路语义分割 点云语义分割算法_点云_38


4.1.3 Recurrent Consolidation Units(RCU)周期性合并单元

RCU将来自空间邻近块的块特征序列作为输入,并返回更新后的块特征序列。RCU是通过GRU实现的。GRU具有学习远程依赖性的能力,范围可以是时间上的也可以是空间上的,GRU在看到块特征的全部输入序列后才会返回更新的块特征,GRU在其内部存储器中保留有关场景的信息,并根据新的观察结果进行更新,通过这种机制来整合和共享所有输入的信息。

点云道路语义分割 点云语义分割算法_特征提取_39

4.2 两种扩展模型

4.2.1 MS-CU(Multi-Scale Blocks + Consolidation Units)

MS-CU网络结构如图所示。

点云道路语义分割 点云语义分割算法_点云道路语义分割_40


网络的输入是三个多尺度的Blocks,每一个Block都含有N个D维的点(不一定是3维的,除了坐标信息外还有可能包括标准化后的坐标以及点的RGB信息等)。通过一个类似PointNet的机制学习每一个Scale下的block的特征(MLP->max-pooling)。然后将块特征(1 x 384)和输入特征进行连接,将连接后的特征作为一系列CU的输入,网络最后接一个MLP输出每一个点在所有类别上的得分(N x M)。

最开始,每个点只能得到它们各自的特征,连接了块特征后,每个点还得到了其相邻点的特征,通过一系列CU后,这种共享特征得到了反复的加强。

4.2.2 GB-RCU(Grid Blocks + Recurrent Consolidation Units)

GB-RCU网络结构如图所示。

点云道路语义分割 点云语义分割算法_特征提取_41


GB-RCU网络的输入是4个来自相邻格网的blocks,每个blocks中都包含由N个D维的点。它通过一个共享权重的MLP和max-pooling学习4个块的特征(4 x 1 x 64,区别于MS-CU),所有的块特征通过一个RCU共享各自的空间上下文,然后RCU返回更新后的块特征。更新后的块特征(1 x 64)和原始块特征(1 x 64)一起附加到输入特征(N x 64)。最后接一个MLP用于计算每一个点在各个类别上的得分(N x M)。

5.PointCNN:可以处理点云的CNN (NIPS 2018)

文章通过一种自定义的 χ-Conv 操作,使常规的Convolution也能处理点云。

参考:https://zhuanlan.zhihu.com/p/96067255

5.1 解决的问题

假设有4个点组成的一个点云,对比常规的2D图片,示意图如下:

图(i)表示2D图片的情况,此时,四个点的位置顺序是固定的。对于点云,其位置顺序有很多可能,如图(ii, iii, iv)所示。如果对图(ii, iii, iv)执行Convolution操作:

点云道路语义分割 点云语义分割算法_算法_42


对于Convolution来说,输入点的顺序发生变化,输出也会变化。这并不是我们希望的结果。因为它们是同一个点云,我们希望即使输入的顺序发生变化,Convolution也能得出相同的结果。所以,点云里面的点的输入顺序,是阻碍Convolution操作的主要问题。论文定义了一个 χ变换矩阵,该矩阵能对某个特定顺序的输入进行处理,得到一个与顺序无关的feature。先经过 χ变换矩阵处理,再执行Convolution的操作:

点云道路语义分割 点云语义分割算法_特征提取_43


其中,不同的输入顺序,对应不同的 χ 变换矩阵。对于以上等式中的fiii和fiv,如果能够使χiii= χiv × II,II满足:

点云道路语义分割 点云语义分割算法_点云道路语义分割_44


这样的话,fiii和fiv理论上就能相等,Convolution的输出不再与输入点的顺序有关。

5.2 算法

5.2.1 类二维CNN操作
先看CNN的卷积(太人性化了,少见这种用简单的东西去类比的作者,简直感动),CNN的输入是[R1,R1,C1]而卷积核的大小是[K,K,C1,C2]从前一层F1中大小为[K, K, C1]的区域生成F2中形状大小为[R2, R2, C2]的特征。其中R2<R1, C2>C1,即特征图的分辨率降低,但特征图数量增加,得到较高层次的信息。

而PointCNN的输入时点集F1 = {(p1,i , f1,i ) : i = 1, 2, …, N1},, 其中p是点的D维坐标(作者没有假设点的维数,所以这里用D,如果是3维空间D就是3),f是点对应的特征。这里N个点到底怎么取,在论文后面有提,这里先放着。对F1用 X-Conv(就是带X变换的卷积)得到F2 = {(p2,i , f2,i ) : f2,i ∈ RC2 , i =1, 2, …, N2}。仿照CNN,这里也要求N2<N1, C2>C1, 所以随着一层一层的映射,点的数量会越来越少,而每个点的特征会越来越多。

点云道路语义分割 点云语义分割算法_卷积_45


上边的是CNN,通过conv提取特征,通过池化降采样,下面是PointCNN,类似。 通过X-Conv把点减少,把特征集中到某些点上。F2中的点怎么选,论文里说他们以后还要改进,暂时的实现是:对分类问题:p2是p1的随机下采样,对语义分割问题:p2是p1的最远点采样。

5.2.2 局部特征的提取

为了实现与conv类似的空间局部相关性,X-conv只作用于局部区域。在F2中的任何一个点,叫做p, 而p在F1中的K临近称作N。所以每一个X-conv针对p的输入是S = {(pi , fi ) : pi ∈ N}, 注意这里S是一个无序集合。不失一般性,S可以表示为KxD的矩阵,P = (p1,p2, …,pK )T 和一个KxC1的矩阵F = (f1, f2, …, fK )T。(一个是点的位置矩阵,一个是特征的矩阵),所以X-Conv的参数有K × (C1 + Cδ ) × C2个。(Cδ 在后面提到)

具体的计算方法是:

点云道路语义分割 点云语义分割算法_算法_46

  1. P′ ← P − p 得到P相对于p的坐标,p目标点;
  2. Fδ ← MLPδ (P′) 将每个点映射到Cδ维的空间中,逐点使用MLP;
  3. F∗ ← [Fδ , F] 把Fδ 和 F拼接起来 F∗ 是一个 K × (Cδ + C1) 矩阵,K卷积核;
  4. X ← MLP(P′) 用P′预测KxK矩阵;
  5. FX ← X × F∗ 到这一步就做完X变换了;
  6. Fp ←Conv(K, FX) 做卷积;

为了计算出点p的feature,首先确定其邻居点集P(使用FPS,或者KNN),按以上算法操作:

点云道路语义分割 点云语义分割算法_算法_47


算法也可以用如下公式来表达:

点云道路语义分割 点云语义分割算法_卷积_48


可以看出,对于不同的顺序,计算出来的χ是不同的。论文中给出了一个feature可视化的结果:

点云道路语义分割 点云语义分割算法_算法_49


点云道路语义分割 点云语义分割算法_卷积_50


可以看到χ矩阵。论文希望通过该矩阵来将邻居点的feature矩阵变得与邻居点的顺序无关。