基于PointNet的迭代方法
文章来源
知乎:https://zhuanlan.zhihu.com/p/289620126
Github:https://github.com/zhulf0804/PCReg.PyTorch
源码分析
目录结构
PCReg.PyTorch
data
CustomDataset.py # 自定义模型的Dataset定义
ModelNet40.py # ModelNet模型的Dataset定义
loss
earth_mover_distance # 推土机距离损失定义
matrics
metrics.py # 计算评价指标
helper.py # 计算R和t的误差
models
benchmark.py # 网络结构定义
fgr.py # Fast Global Registration (FGR) 算法执行点云之间的配准
icp.py # ICP算法执行点云之间的配准
utils
dist.py # 计算的是两组点之间点对点的平方距离
format.py # 读取pcd、npy和pcd文件相互转换
time.py # 一个装饰器,计算传入函数的执行时间
custom_evaluate.py # 评估ICP和基于迭代的网络后结果的性能
custom_train.py # 进行配准任务的训练
modelnet40_evaluate.py # 同上,只是模型换成了modelnet40
modelnet40_train.py # 同上
数据处理
初始化:
CustomData类继承自 PyTorch 的Dataset类,接受数据集根目录、采样点数和指示是否为训练集的参数。根据参数选择训练集或验证集的目录名,读取该目录下的所有点云文件路径。获取数据项:
__getitem__方法用于按索引获取指定数据项。首先从文件列表中获取对应索引的点云文件,然后加载该点云数据。随机选点:对点云数据执行随机选点操作,将点云数据减少到指定的点数。这有助于减小计算复杂度并提高处理速度。
归一化:将点云数据进行归一化处理,将其坐标范围限制在一个固定的范围内。这有助于提高模型的泛化性能和收敛速度。
生成随机变换矩阵:生成一个随机的旋转矩阵和平移向量,用于模拟真实场景中点云之间的相对位置变化。旋转角度范围为 -20 到 20 度,平移范围为 -0.5 到 0.5。
应用变换:将生成的随机旋转矩阵和平移向量应用到参考点云数据,得到源点云数据。
添加随机噪声:如果是训练集,为参考点云和源点云添加随机噪声。这有助于提高模型的鲁棒性,使其能够在噪声环境下更好地执行点云配准。
返回数据:返回预处理后的参考点云、源点云、旋转矩阵和平移向量。这些数据将作为网络的输入和监督信号进行训练。
数据集大小:
__len__方法返回数据集中点云文件的数量。
网络定义
Encoder (PointNet)
这个网络用于提取点云数据的特征,为一个1024维的特征
输入维度:
in_dim(例如 3,表示位置信息)第一个卷积层输出维度:64
ReLU 激活函数
第二个卷积层输出维度:64
ReLU 激活函数
第三个卷积层输出维度:64
ReLU 激活函数
第四个卷积层输出维度:128
ReLU 激活函数
第五个卷积层输出维度:1024
ReLU 激活函数
全局最大池化(沿 num_points 维度):维度变为 (batch_size, 1024)
在每个卷积层之后,我们都添加了一个 ReLU 激活函数,以引入非线性,使得网络能够学习更复杂的特征表示。这种网络结构可以更有效地捕捉点云数据中的信息。在全局最大池化之后,我们得到一个尺寸为 (batch_size, 1024) 的特征向量,可以用于后续任务。
Decoder (Benchmark)
输入点云
x和y的维度:(batch_size, in_dim1, num_points)。使用
PointNet编码器对输入x和y进行特征提取:输出特征维度:
(batch_size, 1024)。
将特征
x_f和y_f进行拼接:拼接后的特征维度:
(batch_size, 2048)。
将拼接后的特征传入解码器。解码器包含一系列全连接层和 ReLU 激活函数:
第一个全连接层输出维度:1024
ReLU 激活函数
第二个全连接层输出维度:1024
ReLU 激活函数
第三个全连接层输出维度:512
ReLU 激活函数
第四个全连接层输出维度:512
ReLU 激活函数
第五个全连接层输出维度:256
ReLU 激活函数
第六个全连接层输出维度:7(输出旋转和平移参数)
输出:
(batch_size, 7),其中前 3 个元素表示平移向量,后 4 个元素表示旋转四元数。
Benchmark 网络首先使用 PointNet 编码器对输入点云 x 和 y 提取特征,然后将两个特征向量拼接在一起。接下来,通过一个解码器(由一系列全连接层和 ReLU 激活函数组成)将拼接后的特征映射到旋转和平移参数。最后,网络输出一个大小为 (batch_size, 7) 的向量,表示点云之间的相对变换。
IterativeNet (IterativeBenchmark)
一个基于迭代方法的点云对其网络,用Pointnet作为编码器,Benchmark作为解码器,多次迭代来优化点云之间的变换
以下是 IterativeBenchmark 网络的各层和维度变化:
输入点云
x和y的维度:(batch_size, in_dim, num_points)。初始化
Benchmark网络。设置迭代次数
niters。初始化变换后的点云
transformed_x为与输入点云x相同。初始化旋转矩阵为单位矩阵,大小为
(batch_size, 3, 3)。初始化平移向量为零矩阵,大小为
(batch_size, 3, 1)。对于
i从0到niters-1进行迭代:使用
Benchmark模型对transformed_x和y进行特征提取,计算旋转矩阵batch_R和平移向量batch_t,并获得变换后的点云transformed_x。更新旋转矩阵和平移向量。
调整变换后的点云
transformed_x的维度顺序。
输出:最终的旋转矩阵
batch_R_res,最终的平移向量batch_t_res和每次迭代后变换的点云transformed_xs。
IterativeBenchmark 网络首先初始化一个 Benchmark 网络,然后对输入点云 x 和 y 进行多次迭代。在每次迭代中,网络计算 transformed_x 和 y 之间的相对变换,并更新旋转矩阵和平移向量。经过 niters 次迭代后,网络输出最终的旋转矩阵、平移向量以及每次迭代后的变换点云。这种迭代策略有助于提高网络的性能和鲁棒性。
Last updated