[点云+深度学习]PointNet论文解析

《PointNet: Deep Learning on Point Sets for 3D Classification and Segmentation》
《PointNet++: Deep Hierarchical Feature Learning on Point Sets in a Metric Space》
《Frustum PointNets for 3D Object Detection from RGB-D Data》

MXNet的PointNet实现:

内容 描述
Zehaos/mx-pointnet 符号式
hnVfly/pointnet.mxnet 命令式

环境配置

系统:Ubuntu14.04
步骤:安装CUDA、安装CuDNN、安装Anaconda
参考:史上最全的ubuntu16.04安装nvidia驱动+cuda9.0+cuDnn7.0

安装CUDA9.0

安装opengl一定不要选

安装完后,配置CUDA的环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
sudo nano /etc/profile

在文件末尾添加:
export PATH=/usr/local/cuda-9.0/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64$LD_LIBRARY_PATH

重启

安装g++(编译cuda例子时需要):
sudo apt-get install build-essential


sudo nano ~/.bashrc

在文件末尾添加:
export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}


sudo nano /etc/profile

在文件末尾添加:
export PATH=/usr/local/cuda/bin:$PATH


sudo nano /etc/ld.so.conf.d/cuda.conf

在文件末尾添加:
/usr/local/cuda/lib64


sudo ldconfig

配置CuDNN7.0

1
2
3
4
5
6
7
8
9
10
11
cd /home/imv/Downloads/cudnn-9.0-linux-x64-v7/cudnn-9/cuda

sudo cp lib64/lib* /usr/local/cuda/lib64/
sudo cp include/cudnn.h /usr/local/cuda/include/

更新链接:
cd /usr/local/cuda/lib64/
sudo chmod +r libcudnn.so.7.0.5
sudo ln -sf libcudnn.so.7.0.5 libcudnn.so.7
sudo ln -sf libcudnn.so.7 libcudnn.so
sudo ldconfig

安装深度学习框架

1
2
3
pip install mxnet-cu90==1.4.0
pip install gluoncv==0.4.0
pip install tensorflow-gpu==1.6.0

代码解析

运行代码

1
2
3
把modelnet40_ply_hdf5_2048.zip解压后放在/data目录下

python train.py

默认参数,实现的是点云分类

  1. 在sys.path中添加当前目录(provider.py)、/models目录(pointnet_cls.py)、/utils目录(tf_util.py
  2. 新建/log目录,将pointnet_cls.py、train.py拷贝一份副本至此文件夹做备份,并生成log_train.txt
  3. 载入/data中的训练集、测试集(/data/modelnet40_ply_hdf5_2048/train_files.txt、/data/modelnet40_ply_hdf5_2048/test_files.txt)
  4. 主体代码(PointNet分类网络):
    架构:输入B×N×3,输出B×40,T-Net+分类器
    损失:两部分构成(classify_loss + mat_diff_loss * reg_weight)
  5. train_one_epoch()函数的思路
    • 读取数据:训练集有5个文件(每个文件中有2048个数据),每个epoch打乱读取这5个文件的顺序,只取每个文件的data键(2048, 2048, 3)-数据、label键(2048, 1)-标签
    • 截取data的前NUM_POINT(取1024)个点(2048, 1024, 3)
    • 打乱data(2048, 1024, 3)、label(2048,)中2048个数据的顺序,并将label展平
    • 算出每个batch的数量num_batches(64=2048//32)
    • 对每个batch的数据batch_data(32, 1024, 3)通过旋转(rotation)、抖动(jittering)做数据增强
      • 旋转:对batch_data中的每个数据(1024, 3)旋转不同的3×3矩阵(对应Ry)
      • 抖动:
        360°

分析代码

使用代码记录

1
2
3
4
5
6
7
8
9
10
11
import numpy as np

# np.squeeze(): 从数组的形状中删除单维度条目,即把shape中为1的维度去掉
a = np.arange(5).reshape(5,1)
a.shape # (5, 1)
np.squeeze(a).shape # (5,)


# np.clip(): 截取,即超出的部分强置为边界部分
a = np.arange(5)
np.clip(a, 2, 4)

使用jupyter分析代码

解决argparse包在jupyter下报错的问题:jupyter notebook:使用argparse包存在的问题及解决

1
2
3
4
parser = argparse.ArgumentParser()
parser.add_argument("--verbosity", help="increase output verbosity")
args = parser.parse_args(args=[]) # 括号内的参数是在jupyter中能使用argparse的关键
print(args)

核心思想

细节

读取h5文件

1
2
3
4
import h5py
filename = "data.h5"
f = h5py.File(filename)
list(f.keys())

在jupyter中可视化点云

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 在jupyter中可视化点云
import numpy as np
import open3d as o3
from open3d import JVisualizer
from open3d import PointCloud, Vector3dVector, draw_geometries

# 保存点云数据
# np.savetxt("pc.csv", pc, delimiter=',')

# 载入点云数据
pc = np.loadtxt("pc.csv", delimiter=",")
pcd = PointCloud()
pcd.points = Vector3dVector(pc)

# 法1: 弹窗可视化点云
# draw_geometries([pcd])

# 法2: 在jupyter中可视化点云
visualizer = JVisualizer()
visualizer.add_geometry(pcd)
visualizer.show()

参考

官方

内容 描述
原始论文:PointNet PointNet主页
代码:pointnet Py2.7、TF1.0.1、Ubuntu14.04(CUDA8.0、cuDNN5.1)
CVPR2017口头报告视频 PointNet
原始论文:PointNet++ PointNet++主页
代码:pointnet++ Py2.7/Py3、TF1.2、Ubuntu14.04
原始论文:Frustum PointNets Frustum PointNets主页
代码:Frustum PointNets Py2.7/Py3、TF1.2/TF1.4、Ubuntu14.04/Ubuntu16.04

博客

内容 描述

运行pointnet++代码前需要先编译tf的运算:
本机环境:Ubuntu 16.04、TF1.6.0、CUDA9.0、cuDNN7.0.5
pointnet2-master/tf_ops/3d_interpolation/tf_interpolate_compile.sh

1
2
# TF1.4
g++ -std=c++11 tf_interpolate.cpp -o tf_interpolate_so.so -shared -fPIC -I /home/amax/anaconda3/lib/python3.6/site-packages/tensorflow/include -I /usr/local/cuda-9.0/include -I /home/amax/anaconda3/lib/python3.6/site-packages/tensorflow/include/external/nsync/public -lcudart -L /usr/local/cuda-9.0/lib64/ -L/home/amax/anaconda3/lib/python3.6/site-packages/tensorflow -ltensorflow_framework -O2 -D_GLIBCXX_USE_CXX11_ABI=0

pointnet++/pointnet2-master/tf_ops/grouping/tf_grouping_compile.sh

1
2
3
4
5
#/bin/bash
/usr/local/cuda-9.0/bin/nvcc tf_grouping_g.cu -o tf_grouping_g.cu.o -c -O2 -DGOOGLE_CUDA=1 -x cu -Xcompiler -fPIC

# TF1.4
g++ -std=c++11 tf_grouping.cpp tf_grouping_g.cu.o -o tf_grouping_so.so -shared -fPIC -I /home/amax/anaconda3/lib/python3.6/site-packages/tensorflow/include -I /usr/local/cuda-9.0/include -I /home/amax/anaconda3/lib/python3.6/site-packages/tensorflow/include/external/nsync/public -lcudart -L /usr/local/cuda-9.0/lib64/ -L/home/amax/anaconda3/lib/python3.6/site-packages/tensorflow -ltensorflow_framework -O2 -D_GLIBCXX_USE_CXX11_ABI=0

pointnet2-master/tf_ops/sampling/tf_sampling_compile.sh

1
2
3
4
5
#/bin/bash
/usr/local/cuda-9.0/bin/nvcc tf_sampling_g.cu -o tf_sampling_g.cu.o -c -O2 -DGOOGLE_CUDA=1 -x cu -Xcompiler -fPIC

# TF1.4
g++ -std=c++11 tf_sampling.cpp tf_sampling_g.cu.o -o tf_sampling_so.so -shared -fPIC -I /home/amax/anaconda3/lib/python3.6/site-packages/tensorflow/include -I /usr/local/cuda-9.0/include -I /home/amax/anaconda3/lib/python3.6/site-packages/tensorflow/include/external/nsync/public -lcudart -L /usr/local/cuda-9.0/lib64/ -L/home/amax/anaconda3/lib/python3.6/site-packages/tensorflow -ltensorflow_framework -O2 -D_GLIBCXX_USE_CXX11_ABI=0

深度学习在点云分割中的应用(CVPR2018)