利用cloudcompare标注的点云数据制作成semantickitti数据格式

今天用自己做的数据集终于跑通了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博客

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值