当前位置:   article > 正文

PointNet++复现、论文和代码研读

pointnet++复现

复现

https://github.com/yanx27/Pointnet_Pointnet2_pytorch

1.创建虚拟环境并进入

conda create -n pointnet++ python=3.7
conda activate pointnet++

2.安装pytorch

查找对应版本,这里cuda是10.1,服务器上只有10.0,10.2和11.1,但我在官网上(https://pytorch.org/get-started/previous-versions/)发现10.2与pytorch1.6也匹配,先不安装cuda10.1试一试。
在这里插入图片描述

# CUDA 10.2
conda install pytorch==1.6.0 torchvision==0.7.0 cudatoolkit=10.2 -c pytorc
  • 1
  • 2

报错:
在这里插入图片描述
随后出现以下内容所以没有管。
在这里插入图片描述

3.分割模型的训练和测试

3.1.下载数据处理数据

将Stanford3dDataset_v1.2_Aligned_Version数据集放在data目录下(代码里改一下数据集路径),运行程序生成npy文件。
cd data_utils
python collect_indoor3d_data.py
在这里插入图片描述

3.2.训练分割模型

python train_semseg.py
参数使用默认值,改了一下log_dir
在这里插入图片描述
报错:在这里插入图片描述
按理说不应该报错,名字都是对的,后面弹出一个窗口,说S3DISDataLoader.py内容较新,选择比较还是覆盖,点击覆盖后问题解决。

报错:
没有tqdm
pip install tqdm

报错:
在这里插入图片描述

room_data = np.load(room_path, allow_pickle=True)
  • 1

在这里插入图片描述
感觉是不是npy生成的有问题,不然为什么前面的npy可以而这个npy报错?把pointnet生成的npy复制到该目录下。但对比了两个工程处理数据的py文件,感觉没有什么区别。但这样操作后程序跑起来了:
在这里插入图片描述
在这里插入图片描述

3.3分割模型的测试

在这里插入图片描述
上面两个是本来就有的,里面有pointnet和pointnet++的预训练模型,可直接用来测试。用Github推荐的MeshLab看可视化效果,左侧真实值,右侧预测值。
在这里插入图片描述

4.分类模型的训练和测试

github上给的不同模型的效果对比:
在这里插入图片描述
_SSG不知道是什么

论文研读

https://proceedings.neurips.cc/paper_files/paper/2017/file/d8bf84be3800d12f74d8b05e9b89836f-Paper.pdf

PointNet++网络结构的搭建借鉴了CNN的思想,通过层次结构应用PointNet(SA层)来提取点云特征,同时在特征提取模块中引入了特殊结构(MSG、MRG)来解决点云密度分布不均匀的问题。
在这里插入图片描述

图中虚线圆圈类似CNN中的卷积,将圆圈内所有点提取为一个特征即为局部特征提取,所以输入点经过SA层后将会变成一个个特征点,最终点云经过一层层SA层抽象为点云的特征。可以看到SA层与CNN中的卷积层非常相似,都是选取中心点,由其领域中的所有点得到特征。但由于点云的性质导致无法直接应用3D CNN。PointNet首先对点云进行标准化(T-Net)再应用MLP,最大池化层等结构来提取整个点云的信息,最终会导致局部特征的丢失。

如何选择局部区域?
在二维图像中,局部区域即每个卷积核,卷积中心就是一个个的像素点,它们排列有序,使用固定大小的卷积核就能有效的覆盖整幅图像。但在点云中,各点之间的距离是不相等的,因此局部区域的中心的选择较为重要,它决定了最终能否有效覆盖整个点云。而局部区域的大小,即邻域的选择也要考虑到点云分布不均的特点。

如何将局部区域中的点信息提取为一个特征点?
在CNN中,特征提取就是简单的卷积操作,对卷积中心及其邻域应用卷积核相乘就能得到一个结果,即局部区域的特征。
PointNet++中使用PointNet来实现特征提取,即对每个局部区域应用小型的PointNet来得到局部区域的信息。

PointNet++定义了一个SA层解决以上两个问题。
单个SA层由采样层、分组层以及PointNet层三个模块组成。采样层用于从输入集合中选出每个局部区域的中心点,分组层用于构建局部区域点集,通过这两层完成局部区域的划分。PointNet层使用小型PointNet网络用于提取局部区域的特征,这一层用于聚合局部区域的特征。

采样层——采样层使用了最远点采样(FPS,farthest point sampling)来进行局部区域中心的选择,这种方式相比随机采样能够更好的覆盖整个输入点集。假设点云中有N个点,用向量d表示每个点的坐标,向量C表示点的特征。由PointNet++的网络结构图可以看出,输入为N*(d+C)的点云,经过采样层,由最远点采样选出了K个局部中心,用于分组层进行区域划分。

分组层——在划分局部区域时使用了球型邻域,将局部区域中心点周围球型邻域的点分为一组,用于后续的特征提取。分组层根据采样层选出的中心点将点云分为了K个不同大小的局部区域,最终输出N1K(d+C),N1为每个局部邻域中点的数量。

邻域大小的选择对特征学习较为重要,在CNN中,使用较小的卷积核一般能获得更好的性能,但并不同样适用于点云。点云的分布不均匀,有些地方稀疏,若使用较小的邻域,那么该局部区域中的点过少会导致PointNet层无法有效的学习到局部信息。为了解决这一问题,PointNet++设计了两种分组策略:多尺度分组与多分辨率分组,如下图:
在这里插入图片描述

多尺度分组(MSG,Multi-scale grouping)即采用不同尺寸的邻域,同时提取特征,并将这些不同尺度的特征组合起来作为局部区域的整体特征。由于在网络浅层时输入点数量较多,因此采样得到的中心点较多,使用MSG方法就意味着要在如此多的邻域中应用PointNet层提取特征,计算量太大。

多分辨率分组(MRG,Multi-resolution grouping)提取到的特征向量由两部分组成,左边的部分(s1)是由上层的3个中心点提取得到的,而每个中心点都是由上上层相应的领域中的点得到的,同时将这些点视为一个大的局部空间,并提取特征(s2)。

当点云的局部区域较为稀疏时,经过一个SA层得到的中心点就更少了,此时s1就不如s2更能表征点云中该区域的特征。当局部区域较为密集时,经过两层抽象得到的特征s1包含的信息更多。

简单概括一下:
MSG是对同一层的点,采用一组不同大小的邻域同时提取特征并组合为整体特征。MRG是分别对不同层次的点进行特征提取,并组合为整体特征。可以看出该方法相比MSG计算效率要更高。

PointNet层——这层对每个局部区域应用PointNet进行特征的提取,最终输出一个个新的特征点,对应输入邻域的局部特征。输入为K组邻域点,使用PointNet对每个局部区域进行特征提取,得到一个长度为C1的特征向量。最终输出为N1*(d+C1)的形式,即N1个特征点组成的点集,此时点的数量相比输入下降了,但每个点的特征却包含了更多的信息。
参考:https://blog.csdn.net/CirnoZhang/article/details/109085303

效果与PointNet进行对比:
在这里插入图片描述
https://blog.csdn.net/toCVer/article/details/126265782
https://blog.csdn.net/CirnoZhang/article/details/109085303(每周学习总结 pointnet++代码解读)

制作自己的数据集流程

分割模型数据集准备

首先看原来的数据集内容:
S3DIS数据集多用于室内点云的语义分割和实例分割(每个柱子桌椅等都是分开标注的)

6个区域:【目录名称】Area1、Area2、Area3、Area4、Area5、Area6
在这里插入图片描述
13个语义元素: 【annotation的类别】天花板ceiling、地板floor、墙壁wall、梁beam、柱column、窗window、门door、桌子table、椅子chair、沙发sofa、书柜bookcase、板board 、混杂元素(其他)clutter

11种场景:【单文件的名称】办公室、会议室、走廊、礼堂、开放空间、大堂、休息室、储藏室、复印室、储藏室和卫生间 office, conference room, hallway, auditorium, open space, lobby, lounge, pantry, copy room, storage and WC

每个区域有不同的房间,如会议室、走廊、办公室、厕所、存储间等。每一类下面有目录Annotations和一个对应名字的txt文件,如conferenceRoom_1.txt。(这里面是xyzrgb)
在这里插入图片描述
Annotations目录下每一类(每类的每个实例)有以类命名的txt文件,里面是xyzrgb。
在这里插入图片描述
每个物体用txt文件存储,每个txt存储了物体坐标和颜色信息。特别要注意的是,该txt文件中没有存储标签信息,其标签信息是用文件名称来进行区分。例如chair txt文件中的数据都是其中一个椅子的点云数据。因此,在正式处理之前,需要进行处理,为每个点补上标签。
上述这个过程的实现是通过PointNet++中的collect_indoor3d_data.py实现的。该脚本文件为每个点生成了标签,并转换为npy文件,加速文件的读取过程。运行collect_indoor3d_data.py处理数据得到:
在这里插入图片描述

数据集的整体流程:
1.通过collect_indor3d将数据进行转换,为每个点分配标签
2.初始化:读取271个小房间的信息,获取采样点信息,由于这个数据集比较大,不利于训练,PointNet++训练之前会将它进行预处理。对每个房间点的数量对其进行随机采样,随机划分划分为1mx1m的block,然后再放入网络进行训练。
3.对输入房间进行随机采样并计算法向量,进行相应归一化操作。

数据集介绍
https://blog.csdn.net/weixin_47142735/article/details/121605323

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/101744
推荐阅读
相关标签
  

闽ICP备14008679号