今天用自己做的数据集终于跑通了mm3d的语义分割模型,浅浅记录一下
以下内容均基于该博客,因此数据格式均需前提调整为该代码所需格式。
【精选】如何将自定义点云转换成semanticKitti格式_如何把自己的pcd文件处理为semantickitti的格式-CSDN博客
1、未标注的pcd格式转换(最终格式为只含有xyz坐标信息及intensity信息,且pcd需要为ascii码格式,如下图所示),大家可根据自己的数据格式选择后续步骤
(1)将binary编码格式的pcd文件转换为ascii编码格式,代码如下
import numpy as np
#pypcd需要去官方下载
from pypcd import pypcd
import os
pcdrootpath ='E:/nanjing/oldpcd'
newpcd = 'E:/nanjing/newpcd'
for i in os.listdir(pcdrootpath):
pcdpath = os.path.join(pcdrootpath, i)
pc = pypcd.PointCloud.from_path(pcdpath)
pc.pc_data['x'] -= pc.pc_data['x'].mean()
with open(os.path.join(newpcd, i), 'w'):# save as binary compressed
newpcdpath = os.path.join(newpcd, i)
pc.save_pcd(newpcdpath, compression='ascii')
(2)仅提取pcd文件中的xyzintensity信息,代码如下
import open3d as o3d
import os
pcdrootpath = 'D:/pointprocess/nanjing/pcd'
newpath ='D:/pointprocess/nanjing/newpcd'
for i in os.listdir(pcdrootpath):
path = os.path.join(pcdrootpath, i)
pcd = o3d.t.io.read_point_cloud(path)
pcd_intensity = pcd.point["intensity"] # 强度
pcd_points = pcd.point["positions"] # 坐标
pcd_intensity = pcd_intensity[:, :].numpy() # 转换为数组类型
pcd_points = pcd_points[:, :].numpy() # 转换为数组类型
# ---------------生成-------------------#
device = o3d.core.Device("CPU:0")
dtype = o3d.core.float32
pcd = o3d.t.geometry.PointCloud(device)
pcd.point["positions"] = o3d.core.Tensor(pcd_points, dtype, device)
pcd.point["intensity"] = o3d.core.Tensor(pcd_intensity, dtype, device)
# 如果要加入颜色法向量等信息,按同样的方式添加
newpcd = os.path.join(newpath, i)
o3d.t.io.write_point_cloud(newpcd, pcd, write_ascii=True)
2、标注后文件最终处理得到的pcd内容如下图所示,步骤如下:
(1)使用cloudcompare标注后的数据选择txt格式保存(txt!!!!后续方便处理),将txt文件中的intensity信息删除,只保留xyzlabel信息,代码如下
import os
def remove_intensity(path,path2):
f = open(path, encoding='utf-8')
line = f.readline()
list1 = []
while line:
a = line.split(" ")
b = a[0:3]
c = a[4:5]
list1.append(b)
list1.append(' ')
list1.append(c)
# list1.append('\n')
# list1.append(c)
line = f.readline()
f.close()
# print(list1)
with open(path2, 'w') as month_file: # 提取后的数据文件
for line in list1:
s = ' '.join(line)
month_file.write(s)
directory1 = 'D:/pointdata/test2/txt'
directory2 = 'D:/pointdata/test2/txtresult'
for file in os.listdir(directory1):
path = os.path.join(directory1,file)
newfile = open(os.path.join(directory2,file),'a')
path2 = os.path.join(directory2,file)
remove_intensity(path, path2)
(2)将上一步处理后的txt转换为pcd,代码如下
import os
import sys
import numpy as np
def creat_pcd(input_path, output_path):
# Lodaing txt
Full_Data = np.loadtxt(input_path)
# Creating pcd
if os.path.exists(output_path):
os.remove(output_path)
Output_Data = open(output_path, 'a')
Output_Data.write(
'# .PCD v0.7 - Point Cloud Data file format\nVERSION 0.7\nFIELDS x y z intensity label\nSIZE 4 4 4 4 4\nTYPE F F F F U\nCOUNT 1 1 1 1 1')
string = '\nWIDTH ' + str(Full_Data.shape[0])
Output_Data.write(string)
Output_Data.write('\nHEIGHT 1\nVIEWPOINT 0 0 0 1 0 0 0')
string = '\nPOINTS ' + str(Full_Data.shape[0])
Output_Data.write(string)
Output_Data.write('\nDATA ascii')
for j in range(Full_Data.shape[0]):
string = ('\n' + str(Full_Data[j, 0]) + ' ' + str(Full_Data[j, 1]) + ' ' + str(Full_Data[j, 2]) + ' ' + str(
Full_Data[j, 3])+ ' ' + str(Full_Data[j, 4]))
Output_Data.write(string)
Output_Data.close()
print('--------------Completed--------------')
txtpath = 'txt/'#处理前的txt文件夹路径
pcdpath = 'pcd/'#处理后的pcd文件夹路径
for txt in os.listdir(txtpath):
pathtxt = os.path.join(txtpath, txt)
num,numtxt =os.path.splitext(txt)
print(num)
with open(os.path.join(pcdpath, num) + '.pcd','w'):
pathpcd = os.path.join(pcdpath, num) + '.pcd'
creat_pcd(pathtxt, pathpcd)
3.将1和2得到的pcd分别进行处理,得到未标注的.bin文件和标注后的.label文件,制作完成嘻嘻
import os
import numpy as np
def read_ori_pcd(input_path):
lidar = []
with open(input_path, 'r') as f:
line = f.readline().strip()
while line:
linestr = line.split(" ")
if len(linestr) == 4:
linestr_convert = list(map(float, linestr))
lidar.append(linestr_convert)
line = f.readline().strip()
return np.array(lidar)
def read_labeled_pcd(filepath):
lidar = []
with open(filepath, 'r') as f:
line = f.readline().strip()
while line:
linestr = line.split(" ")
if len(linestr) == 5:
linestr_convert = list(map(float, linestr))
lidar.append(linestr_convert)
line = f.readline().strip()
return np.array(lidar)
def convert2bin(input_pcd_dir, output_bin_dir):
file_list = os.listdir(input_pcd_dir)
if not os.path.exists(output_bin_dir):
os.makedirs(output_bin_dir)
for file in file_list:
(filename, extension) = os.path.splitext(file)
velodyne_file = os.path.join(input_pcd_dir, filename) + '.pcd'
p_xyzi = read_ori_pcd(velodyne_file)
p_xyzi = p_xyzi.reshape((-1, 4)).astype(np.float32)
min_val = np.amin(p_xyzi[:, 3])
max_val = np.amax(p_xyzi[:, 3])
p_xyzi[:, 3] = (p_xyzi[:, 3] - min_val)/(max_val-min_val)
p_xyzi[:, 3] = np.round(p_xyzi[:, 3], decimals=2)
p_xyzi[:, 3] = np.minimum(p_xyzi[:, 3], 0.99)
velodyne_file_new = os.path.join(output_bin_dir, filename) + '.bin'
p_xyzi.tofile(velodyne_file_new)
def convert2label(input_pcd_dir, output_label_dir):
file_list = os.listdir(input_pcd_dir)
if not os.path.exists(output_label_dir):
os.makedirs(output_label_dir)
for file in file_list:
(filename, extension) = os.path.splitext(file)
velodyne_file = os.path.join(input_pcd_dir, filename) + '.pcd'
p_xyz_label_object = read_labeled_pcd(velodyne_file)
p_xyz_label_object = p_xyz_label_object.reshape((-1, 5))
label = p_xyz_label_object[:, 3].astype(np.int32)
label = label.reshape(-1)
velodyne_file_new = os.path.join(output_label_dir, filename) + '.label'
label.tofile(velodyne_file_new)
if __name__ == "__main__":
ori_pcd_dir = "oripcd"
ori_bin_dir = "bin"
convert2bin(ori_pcd_dir, ori_bin_dir)
labeled_pcd_dir = "labelpcd"
labeled_bin_dir = "label"
convert2label(labeled_pcd_dir, labeled_bin_dir)
参考连接:【精选】如何将自定义点云转换成semanticKitti格式_ply点云转semantickitti数据-CSDN博客Python txt转pcd(带RGB值,点云)_python-lpy 将msg转为pcd-CSDN博客