python 空间法向量可视化_深度学习在几何空间中的应用(一):三维可视化

深度学习在几何空间中的应用(一):三维可视化

前言目前点云方面的研究是一个热门方向,点云分类、零件分割、语义分割等研究正处于热门研究时期;

深度学习大热以来,渐渐地把二维世界里的框架,或移植,或改进,运用到三维世界中来,那么如何将点云可视化呢?This is a question.

下面让我们一起来探索。

可视化

点云数据准备

如无特别说明,本系列使用的数据是ModelNet40,ModelNet40包含了来自40类的12311个三维形状,其中9843个文件用来训练,2468个文件用来测试。

系统环境操作系统:ubuntu16.04或者windows10,建议在Ubuntu下开发

编程软件:PyCharm

语言环境:Python3.6

python包依赖

使用python3.6读取点云文件,需要提取安装numpy、h5py、mayavi、matplotlib,其中安装mayavi的方法如下(前提:python3.x和64位系统):1

2pip install mayavi

pip install PyQt5 # GUI

故所需要的包有:1

2

3

4

5

6

7import os

import sys

import numpy as np

import h5py

from mayavi import mlab

from mpl_toolkits.mplot3d import Axes3D

import matplotlib.pyplot as plt

在线方式(ubuntu16.04系统下)1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # 当前py文件所在的路径

print(BASE_DIR) # 显示py文件当前路径

sys.path.append(BASE_DIR) # 加入到系路径里

# download modelnet40 dataset

# 将数据集下载到当前py文件所处路径里的data文件夹里,假设当前py文件在

# BASE_DIR=E:/PointCloud路径里,那么数据集将下载到E:/PointCloud

DATA_DIR = os.path.join(BASE_DIR, 'data')

if not os.path.exists(DATA_DIR): # 如果不存在此文件夹

os.mkdir(DATA_DIR) # 新建data文件夹

# 数据集应在BASE_DIR/data/modelnet40_ply_hdf5_2048里,如果不存在

# BASE_DIR/data/modelnet40_ply_hdf5_2048文件夹,则下载数据集

# modelnet40_ply_hdf5_2048.zip并解压,且输出.zip文件

if not os.path.exists(os.path.join(DATA_DIR, 'modelnet40_ply_hdf5_2048')):

# 数据集文件网址

www = 'https://shapenet.cs.stanford.edu/media/modelnet40_ply_hdf5_2048.zip'

# 返回path最后的文件名,即zipfile=modelnet40_ply_hdf5_2048.zip

zipfile = os.path.basename(www)

os.system('wget %s; unzip %s' % (www, zipfile)) # wget:下载,unzp: 解压

# zipfile=modelnet40_ply_hdf5_2048.zip

# zipfile[:-4]=modelnet40_ply_hdf5_2048

# 把解压后的文件夹modelnet40_ply_hdf5_2048移到BASE_DIR/data/路径下

os.system('mv %s %s' % (zipfile[:-4], DATA_DIR))

os.system('rm %s' % (zipfile)) # 删除压缩包

离线方式(ubuntu16.04系统或windows10)

如果没有合适的ubuntu环境,那么我们首先通过网站下载数据集,然后利用windows上的解压工具解压到对应的文件夹,文件夹可以对应到在线方式里的路径,本文采用的这种方法,简单粗暴,但是不推荐,不利于代码的自动化。

运行代码或者解压文件夹,将在BASE_DIR/data/modelnet40_ply_hdf5_2048/文件夹里看到一下内容,注意BASE_DIR指的是当前py文件的路径。

读取点云

由上图可以看到,点云文件由.h5文件格式来存储,有关h5格式的介绍请移步这里,下面我们就来读取点云文件,代码如下(以读取ply_data_train1.h5为例):1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20"""

读取H5文件里的键值

"""

import h5py

# ply_data_train1.h5路径

H5_FILE = './data/modelnet40_ply_hdf5_2048/ply_data_train1.h5'

def (h5_filename): # 定义python函数,函数体前后空两行

"""

读取H5文件里的键值

:param h5_filename:

:return:

"""

with h5py.File(h5_filename) as f:

return [item for item in f.keys()]

keys = read_h5file_keys(H5_FILE)

print("key is : %s" % keys)

运行,得到以下结果:1key is : ['data', 'faceId', 'label', 'normal']

其中

'data'对应点云xyz坐标

'label'对应标签

'normal'对应法向量

'faceId'未知

我们感兴趣的是键值data和label

紧接着,读取点云数据,代码如下:1

2

3with h5py.File(H5_FILE) as f:

data = f['data'][:]

label = f['label'][:]

由于数据集较大,所以是否读取成功,可以利用PyCharm里的Scientific Mode来查看,开启姿势位View——>Scientific Mode,可追踪变量变化,如下图

运行程序后,就会看到这样的情形,

点击变量data后的View as Array,就可以在右边的SciView里看见数据,ply_data_train1.h5里共有 2048个物体的点云数据,所以范围在data[0]到data[2047]之间,每一个物体共有 2048 个点,每个点的坐标位(x, y, z).

可以打印出data和label的形状:1

2print(data.shape) # (2048, 2048, 3)

print(label.shpae) # (2048, 1)

显示点云获取坐标1

2

3

4

5

6

7

8

9

10

11

12

13import numpy as np

from mayavi import mlab

x = []

y = []

z = []

num_obj = 1079 # 比如显示第756 + 1个物体

max_num_point = 2048 # 最大渲染点的个数,最大是2048个点

# 依次获取x、y、z的坐标 —— 1D array

x = data[num_obj, 0:max_num_point, 0] # shape为(max_num_point, 1)

y = data[num_obj, 0:max_num_point, 1] # shape为(max_num_point, 1)

z = data[num_obj, 0:max_num_point, 2] # shape为(max_num_point, 1)

点云可视化方法一 —— mayavi1

2

3

4

5

6

7

8

9

10

11

12# ——————————————————————————————————————————————————————————————

# mayavi可视化

# ——————————————————————————————————————————————————————————————

# s为points3d()函数的第四个参数,与x,y和z具有相同的形状,为每个点

# 提供关联的标量值,或者返回标量值的函数f(x,y,z)

# 此标量值可用于调整点的颜色和大小。

s = np.sqrt(x ** 2 + y ** 2 + z ** 2 )

# 设置背景为白色,画布大小为300 * 200

fig = mlab.figure(bgcolor=(1, 1, 1), size=(450, 300))

# https://docs.enthought.com/mayavi/mayavi/auto/mlab_helper_functions.html#mayavi.mlab.points3d

figure = mlab.points3d(x, y, z, s, mode="point", colormap='spectral', scale_factor=1)

mlab.show() # 显示3D点云图

Notice: 使用这种方法,电脑较卡顿。

在这里,使用了mlab.points3d()函数来进行可视化,具体参数这里,需要注意的是,坐标(x, y, z)各为1D array,需要与mayavi里的surf等方法进行区别,在使用时,注意追踪变量变化,可视化结果

点云可视化方法一 —— matplotlib1

2

3

4

5

6

7

8

9# ——————————————————————————————————————————————————————————————

# matplotlib——Axes3D可视化

# ——————————————————————————————————————————————————————————————

# 使用Axes3D()创建3D图像对象

fig = plt.figure()

ax = Axes3D(fig)

# 调用散点图绘制方法绘图并显示出来

ax.scatter(x, y, z)

plt.show()

可视化结果

1

2

3

4

5

6

7

8

9# shape_name.txt文件路径

SHAPE_NAME = '../data/modelnet40_ply_hdf5_2048/shape_names.txt'

# 显示对应物体的名称

# 读取SHAPE_NAME文件,并存储为numpy数组形式

shape_name_list = np.loadtxt(SHAPE_NAME, dtype=bytes).astype(str)

# 查询该物体名称

shape_name = shape_name_list[label[num_obj]]

print('label is: %s' % shape_name)

总结mayavi和TVTK配合可以自定义点云颜色,可支持自定义点云颜色,官方范例请点击这里,mayavi运行时较卡顿,自定义程度较高,可视化语义分割和场景分割时很有用;

matplotlib库里的Axes3D对象可视化点云方法较为简单,自定义程度较低,在论文中要想显示精美的可视化效果图,不太建议用matplotlib库;

后续工作

除了用这两个库,还有一些python工具可以进行可视化,如GUI工具:meshlab、CloudCompare、Point Cloud Library库里的cloudviewer函数等

我的研究发现时利用深度学习对点云数据集进行分类、场景分割、语义分割等,可视化工具是必不缺少的一环,下一步准备学习meshlab,思路是把点云及相关颜色信息保存成.obj文件,然后在meshlab里显示,具体工作请关注我的博客,如果志同道合者,十分欢迎与联系,这是我的邮箱。

本文的完整代码如下(已在win10环境下,在PyCharm里运行成功,数据集是提前下好的,建议在Ubuntu系统尝试,体会linux的命令):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

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94#! python3

# -*- coding:utf-8 -*-

"""

Author : adoredee

Date : November 28th 2018

BlogName : www.kangzhiheng.top

点云显示

"""

import os

import sys

import numpy as np

import h5py

from mayavi import mlab

from mpl_toolkits.mplot3d import Axes3D

import matplotlib.pyplot as plt

BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # 当前py文件所在的路径

sys.path.append(BASE_DIR) # 显示py文件当前路径

print("the path is: %s" % BASE_DIR) # 加入到系路径里

# ply_data_train1.h5路径

H5_FILE = '../data/modelnet40_ply_hdf5_2048/ply_data_train1.h5'

# shape_names.txt文件路径

SHAPE_NAME = '../data/modelnet40_ply_hdf5_2048/shape_names.txt'

def (h5_filename):

"""

读取H5文件里的键值

:param h5_filename:

:return:

"""

with h5py.File(h5_filename) as f:

return [item for item in f.keys()]

keys = read_h5file_keys(H5_FILE)

print("key is : %s" % keys) # ['data', 'faceId', 'label', 'normal']

with h5py.File(H5_FILE) as f:

data = f['data'][:] # 读取主键'data'的值

label = f['label'][:]

print(data.shape) # 2048组,每组2048个点,每个的值位(x,y,z)

print(label.shape)

x = []

y = []

z = []

num_obj = 1079 # 比如显示第num_obj + 1个物体

max_num_point = 2048 # 最大渲染点的个数,最大是2048个点

x = data[num_obj, 0:max_num_point, 0] * 10 # shape为(max_num_point, 1)

y = data[num_obj, 0:max_num_point, 1] * 10 # shape为(max_num_point, 1)

z = data[num_obj, 0:max_num_point, 2] * 10 # shape为(max_num_point, 1)

# ——————————————————————————————————————————————————————————————

# mayavi可视化

# ——————————————————————————————————————————————————————————————

# s为points3d()函数的第四个参数,与x,y和z具有相同的形状,为每个点

# 提供关联的标量值,或者返回标量值的函数f(x,y,z)

# 此标量值可用于调整点的颜色和大小。

s = np.sqrt(x ** 2 + y ** 2 + z ** 2)

# visualization

fig = mlab.figure(bgcolor=(1, 1, 1), size=(450, 300))

figure = mlab.points3d(x, y, z, s, mode="point", colormap='spectral', scale_factor=0.25)

mlab.show()

'''

# ——————————————————————————————————————————————————————————————

# Axes3D可视化

# ——————————————————————————————————————————————————————————————

# 开始绘图

fig = plt.figure()

ax = Axes3D(fig)

ax.scatter(x, y, z)

plt.show()

'''

# 显示对应物体的名称

# 读取SHAPE_NAME文件,并存储为numpy数组形式

shape_name_list = np.loadtxt(SHAPE_NAME, dtype=bytes).astype(str)

# 查询该物体名称

shape_name = shape_name_list[label[num_obj]]

print('label is: %s' % shape_name)

× 请我吃糖~

你可能感兴趣的:(python,空间法向量可视化)