点云深度学习之数据集处理(三)构建自己的点云数据集

您所在的位置:网站首页 如何做数据集 点云深度学习之数据集处理(三)构建自己的点云数据集

点云深度学习之数据集处理(三)构建自己的点云数据集

2024-07-14 23:56| 来源: 网络整理| 查看: 265

转载自:https://blog.csdn.net/SGL_LGS/article/details/105962966

一、三维点云数据的采集

随着科技的迅速发展,目前获得物体三维点云的方法也越来越多。一种是通过硬件设备(深度传感器,结构光等)直接得到物体的三维信息,另一种是通过软件算法进行图像间匹配间接计算出物体的三维信息。常见的方法手段,如图所示: 在这里插入图片描述 这里不再对其中的内容进行展开说明。无论那一种方法,最终目的都是为了获得三维点云数据。

二、三维点云数据上标签

深度学习中,最繁杂且缺少技术含量的事情应该就是为采集的数据上标签。工欲善其事必先利其器,好的标注方法势必会让我们的工作变得更加高效。这里就介绍一种较为方便的点云标注工具。 代码的开源地址:https://github.com/MR-520DAI/semantic-segmentation-editor 之前的博客也有介绍过安装和使用教程:https://blog.csdn.net/lemonxiaoxiao/article/details/112948824 手动标记保存之后,得到的pcd文件前后如下图所示: 在这里插入图片描述 值得注意的是,该软件的一个缺陷就是在进行标记及保存之后的点云文件是不带颜色信息的(该工具原始目标任务是针对室外激光雷达点云的),颜色信息只能通过后处理手段加上去。此外,如果使用PCL自带的XYZL点云类型进行显示可视化需要注意:保存得到的pcd文件数据类型为(TYPE F F F I I)见上图有右侧所示。我在实际读取过程中就发现会报错,解决办法是将(TYPE F F F I I 批量替换成 TYPE F F F U U).

import os from os import listdir, path path_str = 'E:\\标注原始文件' # your directory path txts = [f for f in listdir(path_str) if f.endswith('.pcd') and path.isfile(path.join(path_str, f))] for txt in txts: with open(os.path.join(path_str, txt), 'r') as f: lines = f.readlines() lines[3] = lines[3].replace('I','U') with open(os.path.join(path_str,os.path.splitext(txt)[0]+".pcd"), 'w') as f: f.write(''.join(lines[0:])) 三、点云深度学习数据集处理流程

接下来就介绍如何将标记好的点云数据集,生成网络的输入训练数据(或如何融合到现有的数据集中进行训练)

PCD文件生成TXT文件 这一步主要是将PCD文件的头信息进行去掉,得到只含有点坐标,颜色和标签的数据文件: import os from os import listdir, path path_str = 'E:\\标注原始文件' # your directory path txts = [f for f in listdir(path_str) if f.endswith('.pcd') and path.isfile(path.join(path_str, f))] for txt in txts: with open(os.path.join(path_str, txt), 'r') as f: lines = f.readlines() with open(os.path.join(path_str,os.path.splitext(txt)[0]+".txt"), 'w') as f: f.write(''.join(lines[11:])) 中心化和尺度缩放 这一步的主要目的是将点云中心移动到坐标原点,并将所有点的坐标的绝对值限制在1以内(对于小型数据集仿照的ShapeNet数据格式): # 输入的data数据为点云的坐标信息和标签信息(或者额外的颜色信息与法向量信息) def change_scale(data): #centre xyz_min = np.min(data[:,0:3],axis=0) xyz_max = np.max(data[:,0:3],axis=0) xyz_move = xyz_min+(xyz_max-xyz_min)/2 data[:,0:3] = data[:,0:3]-xyz_move #scale scale = np.max(data[:,0:3]) data[:,0:3] = data[:,0:3]/scale return data 点云的降采样 这一步的主要目的是将每个点云文件点进行规范化到固定的点数,本文中我们采用随机采样的方式。当然如果有好的想法,采样的方式是可以按照需求进行改进的。 def sample_data(data, num_sample): """ data is in N x ... we want to keep num_samplexC of them. if N > num_sample, we will randomly keep num_sample of them. if N < num_sample, we will randomly duplicate samples. """ N = data.shape[0] if (N == num_sample): return data, range(N) elif (N > num_sample): sample = np.random.choice(N, num_sample) return data[sample, ...], sample else: sample = np.random.choice(N, num_sample-N) dup_data = data[sample, ...] return np.concatenate([data, dup_data], 0), list(range(N))+list(sample) 划分训练集与测试集并保存为.H5文件 这一步就是将处理好的数据划分为训练集和测试集,并将其保存为.H5文件。 # train and test number, save data def save_data(data, ratio): """ data is in N x 4 (XYZL) ... ratio of training set to test set if ratio = 0.8 train data is 80%, test data is 20% """ if not os.path.exists('train.h5'): with h5py.File('train.h5') as f: f['data'] = data[0:int(data.shape[0]*ratio),0:3] f['labels'] = data[0:int(data.shape[0]*ratio),4] if not os.path.exists('test.h5'): with h5py.File('test.h5') as f: f['data'] = data[int(data.shape[0]*ratio):,0:3] f['labels'] = data[int(data.shape[0]*ratio):,4]

到此就完成。当然上面的代码只是方法的演示,针对不同数据需要进行不同的调整。最后给一个相对完整的代码,同样是仅供参考:

#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Wed Sep 25 21:53:03 2019 @author: xxx """ import os import sys import numpy as np import h5py BASE_DIR = os.path.dirname(os.path.abspath(__file__)) sys.path.append(BASE_DIR) def getDataFiles(list_filename): return [line.rstrip() for line in open(list_filename)] def loadDataFile(path): data = np.loadtxt(path) point_xyz = data[:,0:3] # 下面的ins_label, sem_label和obj_lable # 需要根据自己的实际进行赋值(以下只是我的一个示例,就不再解释) ins_label = (data[:,3]).astype(int) find_index = np.where(ins_label>=1) sem_label = np.zeros((data.shape[0]), dtype=int) obj_lable = data[:,4] sem_label[find_index] = obj_lable[find_index]+1 return point_xyz, ins_label, sem_label, obj_lable def change_scale(data): #centre xyz_min = np.min(data[:,0:3],axis=0) xyz_max = np.max(data[:,0:3],axis=0) xyz_move = xyz_min+(xyz_max-xyz_min)/2 data[:,0:3] = data[:,0:3]-xyz_move #scale scale = np.max(data[:,0:3]) # change_data[:,0:3] = data[:,0:3]/scale # return data[:,0:3]/scale return data[:,0:3] def sample_data(data, num_sample): """ data is in N x ... we want to keep num_samplexC of them. if N > num_sample, we will randomly keep num_sample of them. if N < num_sample, we will randomly duplicate samples. """ N = data.shape[0] if (N == num_sample): return data, range(N) elif (N > num_sample): sample = np.random.choice(N, num_sample) return data[sample, ...], sample else: sample = np.random.choice(N, num_sample-N) dup_data = data[sample, ...] return np.concatenate([data, dup_data], 0), list(range(N))+list(sample) if __name__ == "__main__": DATA_FILES =getDataFiles(os.path.join(BASE_DIR, 'file_path.txt')) num_sample = 4096*2 DATA_ALL = [] for fn in range(len(DATA_FILES)): print(DATA_FILES[fn]) current_data, current_ins_label, current_sem_label,current_obj_lable = loadDataFile(DATA_FILES[fn]) change_data = change_scale(current_data) # data_sample,index = sample_data(change_data, num_sample) data_label = np.column_stack((change_data,current_ins_label,current_sem_label,current_obj_lable)) DATA_ALL.append(data_label) output = np.vstack(DATA_ALL) output = output.reshape(-1,num_sample,6) # 这里没将训练测试集单独分开 if not os.path.exists('4096_4096_no_scale.h5'): with h5py.File('4096_4096_no_scale.h5') as f: # sample = np.random.choice(8192, 2048) f['data'] = output[:,:,0:3] f['pid'] = output[:,:,3] f['seglabel'] = output[:,:,4] f['obj'] = output[:,:,5]


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3