3D目标检测——代码理解——OpenPCDet:数据处理适应自己的点云数据

3D⽬标检测——代码理解——OpenPCDet:数据处理适应⾃⼰的点云数据
我的点云数据形式是(x,y,z,r)类型的,直接读取运⽤就⾏了,然后再进⼀步处理。
以下代码是my_datasets的从⽂件中读取和保存的代码
import numpy as np
import copy
import pickle
import os
import json
import numpy as np
import pcl
import pandas
import sys
import random
from skimage import io
from..dataset import DatasetTemplate
from pathlib import Path
class RobosenseDataset(DatasetTemplate):
def__init__(self,dataset_cfg,class_names,training=True, root_path=None,logger =None):
#参数:配置⽂件dataset_cfg, 要分类的类名class_names, 是否为训练training= True,
# 数据集的路径root_path=None,    ⽇志⽂件logger = None
# 这⾥由于是类继承的关系,所以root_path在⽗类中已经定义
#print("即将运⾏初始化")
super().__init__(
dataset_cfg = dataset_cfg,class_names=class_names,
training = training, root_path = root_path,logger = logger
)
#⽤于存放⽂件路径的列表
self.files_list_pcd =[]
self.files_list_label =[]
self.files_list_label_train =[]
self.files_list_label_val =[]
self.files_list_pcd_train =[]
self.files_list_pcd_val =[]
self.split = self.dataset_cfg.DATA_de]
self.include_robosense_de)
def include_robosense_data(self,mode):
if self.logger is not None:
self.logger.info('Loading robosense dataset')
robosense_infos =[]
'''
INFO_PATH:{
'train':[robosense_infos_train.pkl],
'test':[robosense_infos_val.pkl],}
'''
for info_path in self.dataset_cfg.INFO_PATH[mode]:
info_path =_path)+'/'+ info_path
#info_path = _path/ info_path
if not Path(info_path).exists():
continue
continue
with open(info_path,'rb')as f:
infos = pickle.load(f)
d(infos)
if self.logger is not None:
self.logger.info('Total samples for robosense dataset: %d'%(len(robosense_infos))) #根据数据地址的路径,获取路径下⽂件夹的名字列表
def get_folder_list(self,root_path):
folder_list =[]
root_path =root_path
#读取该⽬录下所有⽂件夹的名字,并组成⼀个列表
folder_list = os.listdir(root_path)
return folder_list
#根据⽂件夹的列表,返回包含所有⽂件名的列表 files_list_pcd 和files_list_label
def get_files_name_list(self):
folder_list =[]
folder_list = _folder__path)
files_list_pcd =[]
files_list_label =[]
for per_folder in folder_list:
#⼀条路的⽂件夹的路径one_road_path
one_road_path =_path+per_folder+'/')
#⼀条路下⽂件夹下的⽂件列表 one_road_list =['label','pcd']
one_road_list = _folder_list(one_road_path)
for one_folder in one_road_list:
if one_folder =='pcd':
pcd_path =str(one_road_path+one_folder)
if one_folder =='label':
label_path =str(one_road_path+one_folder)
#获取pcd⽂件夹下⾯的⽂件名,并将⽂件的完整路径添加到列表⾥
pcd_files = _folder_list(pcd_path)
for thisfile in pcd_files:
dswith(".pcd"):
files_list_pcd.append(str(pcd_path+'/'+thisfile))
#获取label⽂件夹下⾯的⽂件名,并将⽂件的完整路径添加到列表⾥
label_files = _folder_list(label_path)
for thisfile in label_files:
dswith(".json"):
files_list_label.append(str(label_path +'/'+ thisfile))
#返回files_list_pcd和files_list_label的列表,
# 该列表内包含了所有pcd和label⽂件的路径名
return files_list_pcd,files_list_label
#根据label的路径,得到对应的pcd路径
def from_label_path_to_pcd_path(self,single_label_path):
#根据label的路径,推出来pcd相应的路径,两者在倒数第⼆个⽂件夹不同
single_pcd_path =''
strl1 ='label'
strl2 ='.json'
if strl1 in single_label_path:
single_pcd_path = single_place(strl1,'pcd')
if strl2 in single_pcd_path:
single_pcd_path = single_place(strl2,'.pcd')
single_pcd_path = single_place(strl2,'.pcd')
#由此得到了label对应的pcd⽂件的路径:single_pcd_path
return single_pcd_path中华人民共和国律师法
# 根据label⽂件路径列表,返回所有标签的数据
def get_all_labels(self,num_workers =4,files_list_label=None):
import concurrent.futures as futures
#根据⼀个label⽂件的路径single_label_path,获取该⽂件内的信息
#信息包括:type, center ,size,rotation,id等信息
global i
i =0
def get_single_label_info(single_label_path):
global i
i=i+1
single_label_path = single_label_path
#打开⽂件
with open(single_label_path,encoding ='utf-8')as f:关于切实做好征地拆迁管理工作的紧急通知
labels = json.load(f)
#定义⼀个空字典,⽤于存放当前帧label所有objects中的信息
single_objects_label_info ={}
single_objects_label_info['single_label_path']= single_label_path
single_objects_label_info['single_pcd_path']= self.from_label_path_to_pcd_path(single_label_path)
single_objects_label_info['name']= np.array([label['type']for label in labels['labels']])
single_objects_label_info['box_center']= np.array([[label['center']['x'], label['center']['y'],label['center']['z']]for  label in labels['labels']])
single_objects_label_info['box_size']= np.array([[label['size']['x'],label['size']['z'],label['size']['z']]for label in labels['labels']])
single_objects_label_info['box_rotation']= np.array([[label['rotation']['roll'],label['rotation']['pitch'],label['rotation']['yaw']]for label in labels['labels']])            single_objects_label_info['tracker_id']= np.array([ label['tracker_id']for label in labels['labels']])
box_center = single_objects_label_info['box_center']
box_size = single_objects_label_info['box_size']
box_rotation = single_objects_label_info['box_rotation']
rotation_yaw = box_rotation[:,2].reshape(-1,1)
gt_boxes = np.concatenate([box_center,box_size,rotation_yaw],axis=1).astype(np.float32)
single_objects_label_info['gt_boxes']= gt_boxes
print("The current processing progress is %d / %d "%(i,len(files_list_label)))
return single_objects_label_info
files_list_label = files_list_label
with futures.ThreadPoolExecutor(num_workers)as executor:
infos = executor.map(get_single_label_info,files_list_label)
infos =list(infos)
print("*****************************Done!***********************")
print("type  of  infos :",type(infos))
print("len  of  infos :",len(infos))
#此时的infos是⼀个列表,列表⾥⾯的每⼀个元素是⼀个字典,
#每个元素⾥⾯的内容是当前帧的信息
return infos
def__len__(self):
if self._merge_all_iters_to_one_epoch:
return bosense_infos)* al_epochs
return bosense_infos)
#去掉⼀帧⾥⾯⽆效的点云数据
def remove_nan_data(self,data_numpy):
data_numpy = data_numpy
data_pandas = pandas.DataFrame(data_numpy)
#删除任何包含nan的所在⾏ (实际有三分之⼀的数据⽆效,是[nan, nan, nan, 0.0])
data_pandas = data_pandas.dropna(axis=0,how='any')
data_pandas = data_pandas.dropna(axis=0,how='any')
data_numpy = np.array(data_pandas)
return data_numpy
#根据每⼀帧的pcd⽂件名和路径single_pcd_path,
石点头# 得到这⼀帧中的点云数据,返回点云的numpy格式(M,4)
def get_single_pcd_info(self,single_pcd_path):
single_pcd_path = single_pcd_path
single_pcd_points = pcl.load_XYZI(single_pcd_path)
#将点云数据转化为numpy格式
single_pcd_points_np = single__array()
#去掉⼀帧点云数据中⽆效的点
single_pcd_points_np = ve_nan_data(single_pcd_points_np) #print(single_pcd_points_np)
#将点云数据转化为list格式
#single_pcd_points_list =single__list()
return single_pcd_points_np
# 根据名字,去掉相应的信息,主要针对single_objects_label_info
# single_objects_label_info ⾥关于‘unknown’的数据信息
def drop_info_with_name(self,info,name):
ret_info ={}
info = info
keep_indices =[ i for i,x in enumerate(info['name'])if x != name] for key in info.keys():
if key =='single_label_path'or key =='single_pcd_path':
ret_info[key]= info[key]
continue
ret_info[key]= info[key][keep_indices]
return ret_info
#根据训练列表label的数据,得到对应的pcd的路径列表list
def from_labels_path_list_to_pcd_path_list(self,labels_path_list):
pcd_path_list =[]
for m in labels_path_list:
pcd_path_list.append(self.from_label_path_to_pcd_path(m)) return pcd_path_list
#实现列表相减的操作,从被减数list_minute中去掉减数list_minus的内容
def list_subtraction(self,list_minute,list_minus):
list_difference =[]
for m in list_minute:
if m not in list_minus:
list_difference.append(m)
return list_difference
def__getitem__(self,index):张志俊解密太极拳
if self._merge_all_iters_to_one_epoch:
index = index %bosense_infos)
single_objects_label_info = copy.bosense_infos[index])        single_label_path = single_objects_label_info['single_label_path']
single_pcd_path = self.from_label_path_to_pcd_path(single_label_path)
#得到点云数据,且是有效的点云数据,返回点云的numpy格式(M,4)        points = _single_pcd_info(single_pcd_path)
#定义输⼊数据的字典,包含:points,⽂件的路径,。。?
input_dict ={
'points': points,
'frame_id': single_pcd_path,
'single_pcd_path':single_pcd_path,
}
}
# 在single_objects_label_info字典⾥,剔除关于'unknown' 的信息
single_objects_label_info = self.drop_info_with_name(info=single_objects_label_info,name='unknown')
name =single_objects_label_info['name']#(N,)
box_center = single_objects_label_info['box_center']#(N,3)
box_size = single_objects_label_info['box_size']#(N,3)
box_rotation  = single_objects_label_info['box_rotation']#(N,3)
tracker_id = single_objects_label_info['tracker_id']#(N,)
#以下是将上⾯的3D框的数据转化为统⼀的数据格式
#数据格式为:(N,7),分别代表 (N, 7) [x, y, z, l, h, w, r]
# gt_boxes: [x, y, z, dx, dy, dz, heading], (x, y, z) is the box center"""
rotation_yaw = box_rotation[:,2].reshape(-1,1)
gt_boxes = np.concatenate([box_center,box_size,rotation_yaw],axis=1).astype(np.float32) #print(gt_boxes.shape)
#print(type(gt_boxes))
input_dict.update({
'gt_names':name,
'gt_boxes':gt_boxes,
'tracker_id':tracker_id
})
#print(input_dict)
# 将点云与3D标注框均转⾄统⼀坐标定义后,送⼊数据基类提供的 self.prepare_data()
#data_dict = input_dict
data_dict = self.prepare_data(data_dict=input_dict)
return data_dict
#由⽂件的完整路径得到⽂件的名字(去掉多余的信息)
def from_filepath_get_filename(self,filepath):
filename =''
filepath = filepath
#得到⼀个元祖tuple,(⽬录,⽂件名)
filepath_and_filename = os.path.split(filepath)
filename = filepath_and_filename[1]
#得到⽂件名+后缀,得到⼀个元祖tuple,(⽂件名,后缀)
filename_and_extension = os.path.splitext(filename)
filename = filename_and_extension[0]
中国给水排水编辑部return filename
#
def create_groundtruth_database(self,info_path =None,used_classes =None,split ='train'):
import torch
#database_save_path = str(_path))+'/'+('gt_database' if split =='train' else ('gt_database_%s'%split)) #db_info_save_path = str(_path))+'/'+('robosense_dbinfos_%s.pkl'%split)
database_save_path = _path)/('gt_database'if split =='train'else('gt_database_%s'%split))
yyf lilydb_info_save_path = _path)/('robosense_dbinfos_%s.pkl'%split)
database_save_path.mkdir(parents=True,exist_ok=True)
all_db_infos ={}
with open(info_path,'rb')as f:
infos = pickle.load(f)
for k in range(len(infos)):
print('gt_database sample:%d/%d'%(k+1,len(infos)))
info = infos[k]
#print("---------------去掉unknown之前的info--------------")
#print(info)
#去掉信息中 unknown的类别的信息
info = self.drop_info_with_name(info=info,name='unknown')
#print("---------------去掉unknown之后的info--------------")

本文发布于:2024-09-22 05:38:02,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/233444.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   路径   列表   得到   件夹   字典
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议