前面我们提到了PointNet的一个缺陷,即没有提取局部特征(与全是MLP有关) 这一过程。这在实际使用过程中该缺点往往会导致模型泛化能力有限,特别是在复杂场景下。

那么作者在PointNet++文章中(总体结构图如上),主要针对三个问题,提出了三种解决方法,分别为:
问题1:一个点云图往往有非常多的点,这会造成计算量过大而限制模型使用,如何解决?
因为考虑到现实场景中由雷达或者深度相机产生的点云数据往往数据量过大,导致模型的运算量大难以落地,且不同点云数据间点的数量不等,这在训练的时候很难进行批量训练。
作者的解决思路就是从所有的点云数据中(假设有N个点)采样N’个点,而且希望 这 N’个点能够包含尽可能多的有用信息。所以作者提出了一种叫做 farthest point sampling (FPS) algorithm,中文翻译就是最远点采样算法来实现从N个点中采样N’个点。
这个最远点采样算法(FPS)的流程如下:
(1)随机选择一个点作为初始点作为已选择采样点;
(2)计算未选择采样点集中每个点与已选择采样点集之间的距离distance,将距离最大的那个点加入已选择采样点集,
(3)更新distance,一直循环迭代下去,直至获得了目标数量的采样点。
代码实现如下
def farthest_point_sample(xyz, npoint):
"""
Input:
xyz: pointcloud data, [B, N, 3]
npoint: number of samples
Return:
centroids: sampled pointcloud index, [B, npoint]
"""
device = xyz.device
B, N, C = xyz.shape
centroids = torch.zeros(B, npoint, dtype=torch.long).to(device)
distance = torch.ones(B, N).to(device) * 1e10
farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device)
batch_indices = torch.arange(B, dtype=torch.long).to(device)
for i in range(npoint):
centroids[:, i] = farthest
centroid = xyz[batch_indices, farthest, :].view(B, 1, 3)
dist = torch.sum((xyz - centroid) ** 2, -1)
mask = dist < distance
distance[mask] = dist[mask]
farthest = torch.max(distance, -1)[1]
return centroids
问题2:如何将点集划分为不同的区域,并获取不同区域的局部特征?
上面已经对原始点云数据进行了最远点采样,降低了数据的冗余度,减少了PointNet++模型的输入大小,但是并未进行局部特征的提取。
这里我们回忆一下CNN模型是如何进行局部特征提取的呢?
(CNN:https://www.jianshu.com/p/fe428f0b32c1)
我们知道在CNN中,局部特征往往由图片/特征图的 k × × ×k 区域与一个大小为 k × × ×k 的卷积核通过点乘求和获得的。受到CNN的启发,作者也想在3D点集当中同样需要找到结构相同的子区域,和对应的区域特征提取器,一个名为Ball query方法的group策略应运而生。
具体作者怎么做的呢?可以总结如下:
1. 确定子区域
(1)预设搜索区域的半径R与子区域的点数K
(2)上面提取出来了 N’ 个点,作为 N’ 个centriods。以这 N’个点为球心,画半径为R的球体(叫做query ball,也就是搜索区域)。
(3)在每个以centriods的球心的球体内搜索离centriods最近的的点(按照距离从小到大排序,找到K个点)。如果query ball的点数量大于规模K,那么直接取前K个作为子区域;如果小于K,那么直接对某个点重采样,凑够规模K
(4)获取所有 N’个centriods对应的N’个子区域,每个子区域K个点。这里的K个点有点CNN中k × × ×k
区域的感觉。
至此,作者介绍了如何像CNN那样,实现子区域的定义,进而实现局部特征的提取。
2. Grouping layer
- 对Sampling layer而言,就是在所有的点云数据中(假设有N个点)采样 N’个点;假设网络的输入为N × × ×( d d d+ C C C)的张量,其中N是点云数据的数据点数量,d为xyz坐标(三维),C是点上的特征(用来形容点的属性的,一般为0),那么通过Sampling layer后,网络的输出就变成了N’ × × ×( d d d+ C C C) 。
- 对Grouping layer而言,就是以上面采样的 N’个点为中心找到N’个子区域,每个子区域包含K个点,每个点的维度为 ( d d d + C C C)。那么通过Grouping layer后,网络的输出就变成N’ × × ×K × × ×( d d d+ C C

最低0.47元/天 解锁文章
494






