ModelNet40 Pretreatment

该代码来自于AlexGeControl,如果侵犯到您的权益,我会删除文章
由于ModelNet40默认的文件格式并非常用的.pcd和.ply形式,在使用该数据集前,先对数据集进行预处理,将.off的点读入到.ply文件中。

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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import os
import argparse
import numpy as np
from plyfile import PlyData
from plyfile import PlyElement

'''
从off文件中读取点云信息
输入:filename-->off文件路径
'''


def read_off(filename):
points = [] # 读取的点
faces = [] # 读取到的faces
# 以只读方式打开文件
with open(filename, 'r') as f:
# 读取文件的第一行
first = f.readline()
# 如果第一行的长度>4,则只获取前三个值,以' '作为分隔符
if (len(first) > 4):
n, m, c = first[3:].split(' ')[:]
else:
# 否则删除最后的空格,将所有数据读入
n, m, c = f.readline().rstrip().split(' ')[:]
n = int(n)
m = int(m)
for i in range(n):
value = f.readline().rstrip().split(' ')
points.append([float(x) for x in value])
for i in range(m):
value = f.readline().rstrip().split(' ')
faces.append([int(x) for x in value])
points = np.array(points)
faces = np.array(faces)
return points, faces

# 将点写入ply文件中
def export_ply(cloud, filename):
# 创建输出的点集,其数据为xyz,数据类型为float
vertex = np.zeros(cloud.shape[0], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')])
for i in range(cloud.shape[0]):
vertex[i] = (cloud[i][0], cloud[i][1], cloud[i][2])
# 将点云数据写入到.ply文件中(使用PlyData API)
ply_out = PlyData([PlyElement.describe(vertex, 'vertex', comments=['vertices'])])
# 将.off文件的文件名(除了后四个字符,即.off)+.ply作为最后输出的文件名
ply_filename = filename[:-4] + '.ply'
ply_out.write(ply_filename)

# 将.off文件写入.ply文件中
def write_ply_points_only_from_off(ply_data_dir, off_data_dir):
# 读取路径下的文件
cat = os.listdir(off_data_dir)
for i in range(len(cat)):
# 设定输入的路径和输出的路径,输出的路径为输入的文件名.ply
print('writing ', i + 1, '/', len(cat), ':', cat[i])
filename = os.path.join(off_data_dir, cat[i])
out = os.path.join(
ply_data_dir,
f'{os.path.splitext(cat[i])[0]}.ply'
)
points, faces = read_off(filename)
export_ply(points, out)

# 在.ply输出文件夹中创建与.off输入文件夹相同的文件结构
def create_ply_file(off_data_dir, ply_data_dir):
cat = os.listdir(off_data_dir)
for i in range(len(cat)):
if not os.path.exists(os.path.join(ply_data_dir, cat[i], 'train')):
os.makedirs(os.path.join(ply_data_dir, cat[i], 'train'))
print('create success :'+ply_data_dir+cat[i]+'train')
for i in range(len(cat)):
if not os.path.exists(os.path.join(ply_data_dir, cat[i], 'test')):
os.makedirs(os.path.join(ply_data_dir, cat[i], 'test'))
print('create success :'+ply_data_dir+cat[i]+'train')



def get_arguments():
""" gets command line arguments.
:return:
"""

# init parser:
parser = argparse.ArgumentParser("Downsample ModelNet40 by category.")

# add required and optional groups:
required = parser.add_argument_group('Required')
optional = parser.add_argument_group('Optional')

# add required:
required.add_argument(
"-i", dest="input", help="Input path of ModelNet 40 dataset in off format.",
required=True
)
required.add_argument(
"-o", dest="output", help="Output path of ModelNet 40 dataset in ply format.",
required=True
)

# parse arguments:
return parser.parse_args()


if __name__ == '__main__':
arguments = get_arguments()
create_ply_file(arguments.input, arguments.output)
cat = os.listdir(arguments.input)
for i in range(len(cat)):
model40Dir = os.listdir(arguments.input + '/' + cat[i])
# print(cat[i])
for j in range(len(model40Dir)):
# print(model40Dir[j])
write_ply_points_only_from_off(arguments.output + '/' + cat[i] +'/'+model40Dir[j],
arguments.input + '/' + cat[i] + '/' + model40Dir[j])



感谢您的阅读。 🙏 关于转载请看这里