def convert_pc2ply(anno_path, save_path): """ Convert original dataset files to ply file (each line is XYZRGBL). We aggregated all the points from each instance in the room. :param anno_path: path to annotations. e.g. Area_1/office_2/Annotations/ :param save_path: path to save original point clouds (each line is XYZRGBL) :return: None; note: Physically, each room will generate four files, including raw_pc.ply, sub_pc.ply, sub_pc.pkl for the kdtree and proj_idx.pkl for each raw point's nearest neighbor in the sub_pc ) """ # store points and labels for the room(correspond to the anno_path), yc data_list = [] for f in glob.glob(join(anno_path, '*.txt')): class_name = os.path.basename(f).split('_')[0] if class_name not in gt_class: # note: in some room there is 'staris' class.. class_name = 'clutter' pc = pd.read_csv(f, header=None, delim_whitespace=True).values labels = np.ones((pc.shape[0], 1)) * gt_class2label[class_name] data_list.append(np.concatenate([pc, labels], 1)) # Nx7 # translate the data by xyz_min--yc pc_label = np.concatenate(data_list, 0) # Nx7 as a np object xyz_min = np.amin(pc_label, axis=0)[0:3] pc_label[:, 0:3] -= xyz_min # manage data types and save in PLY format--yc xyz = pc_label[:, :3].astype(np.float32) colors = pc_label[:, 3:6].astype(np.uint8) labels = pc_label[:, 6].astype(np.uint8) write_ply(save_path, (xyz, colors, labels), ['x', 'y', 'z', 'red', 'green', 'blue', 'class']) # save sub_cloud and KDTree file sub_xyz, sub_colors, sub_labels = DP.grid_sub_sampling( xyz, colors, labels, sub_grid_size) sub_colors = sub_colors / 255.0 sub_ply_file = join(sub_pc_folder, save_path.split('/')[-1][:-4] + '.ply') write_ply(sub_ply_file, [sub_xyz, sub_colors, sub_labels], ['x', 'y', 'z', 'red', 'green', 'blue', 'class']) search_tree = KDTree(sub_xyz) kd_tree_file = join(sub_pc_folder, str(save_path.split('/')[-1][:-4]) + '_KDTree.pkl') with open(kd_tree_file, 'wb') as f: pickle.dump(search_tree, f) # nearest nb index list for xyz when searching using the sub-sampled PC generated kdtree--yc # https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KDTree.html proj_idx = np.squeeze(search_tree.query(xyz, return_distance=False)) proj_idx = proj_idx.astype(np.int32) proj_save = join(sub_pc_folder, str(save_path.split('/')[-1][:-4]) + '_proj.pkl') with open(proj_save, 'wb') as f: pickle.dump([proj_idx, labels], f)
def convert_for_test(filename, output_dir, grid_size=0.001, protocol="field"): original_pc_folder = os.path.join(output_dir, 'test') if not os.path.exists(original_pc_folder): os.mkdir(original_pc_folder) sub_pc_folder = os.path.join(output_dir, 'input_{:.3f}'.format(grid_size)) if not os.path.exists(sub_pc_folder): os.mkdir(sub_pc_folder) basename = os.path.basename(filename)[:-4] data = numpy.loadtxt(filename) points = data[:, 0:3].astype(numpy.float32) if protocol == "synthetic" or protocol == "field_only_xyz": # TODO : hack must be remove colors = numpy.zeros((data.shape[0], 3), dtype=numpy.uint8) elif protocol == "field": adr = normalize(data[:, 3:-1]) * 255 colors = adr.astype(numpy.uint8) else: exit("unknown protocol") field_names = ['x', 'y', 'z', 'red', 'green', 'blue'] #Save original full_ply_path = os.path.join(original_pc_folder, basename + '.ply') helper_ply.write_ply(full_ply_path, [points, colors], field_names) # save sub_cloud and KDTree file sub_xyz, sub_colors = DP.grid_sub_sampling(points, colors, grid_size=grid_size) sub_colors = sub_colors / 255.0 sub_ply_file = os.path.join(sub_pc_folder, basename + '.ply') helper_ply.write_ply(sub_ply_file, [sub_xyz, sub_colors], field_names) labels = numpy.zeros(data.shape[0], dtype=numpy.uint8) search_tree = sklearn.neighbors.KDTree(sub_xyz, leaf_size=50) kd_tree_file = os.path.join(sub_pc_folder, basename + '_KDTree.pkl') with open(kd_tree_file, 'wb') as f: pickle.dump(search_tree, f) proj_idx = numpy.squeeze(search_tree.query(points, return_distance=False)) proj_idx = proj_idx.astype(numpy.int32) proj_save = os.path.join(sub_pc_folder, basename + '_proj.pkl') with open(proj_save, 'wb') as f: pickle.dump([proj_idx, labels], f)
def convert_pc2ply(anno_path, save_path): """ Convert original dataset files to ply file (each line is XYZRGBL). We aggregated all the points from each instance in the room. :param anno_path: path to annotations. e.g. Area_1/office_2/Annotations/ :param save_path: path to save original point clouds (each line is XYZRGBL) :return: None """ data_list = [] for f in glob.glob(join(anno_path, '*.txt')): class_name = os.path.basename(f).split('_')[0] if class_name not in gt_class: # note: in some room there is 'staris' class.. class_name = 'clutter' pc = pd.read_csv(f, header=None, delim_whitespace=True).values labels = np.ones((pc.shape[0], 1)) * gt_class2label[class_name] data_list.append(np.concatenate([pc, labels], 1)) # Nx7 pc_label = np.concatenate(data_list, 0) xyz_min = np.amin(pc_label, axis=0)[0:3] pc_label[:, 0:3] -= xyz_min xyz = pc_label[:, :3].astype(np.float32) colors = pc_label[:, 3:6].astype(np.uint8) labels = pc_label[:, 6].astype(np.uint8) write_ply(save_path, (xyz, colors, labels), ['x', 'y', 'z', 'red', 'green', 'blue', 'class']) # save sub_cloud and KDTree file sub_xyz, sub_colors, sub_labels = DP.grid_sub_sampling( xyz, colors, labels, sub_grid_size) sub_colors = sub_colors / 255.0 sub_ply_file = join(sub_pc_folder, save_path.split('/')[-1][:-4] + '.ply') write_ply(sub_ply_file, [sub_xyz, sub_colors, sub_labels], ['x', 'y', 'z', 'red', 'green', 'blue', 'class']) search_tree = KDTree(sub_xyz) kd_tree_file = join(sub_pc_folder, str(save_path.split('/')[-1][:-4]) + '_KDTree.pkl') with open(kd_tree_file, 'wb') as f: pickle.dump(search_tree, f) proj_idx = np.squeeze(search_tree.query(xyz, return_distance=False)) proj_idx = proj_idx.astype(np.int32) proj_save = join(sub_pc_folder, str(save_path.split('/')[-1][:-4]) + '_proj.pkl') with open(proj_save, 'wb') as f: pickle.dump([proj_idx, labels], f)
def load_sub_sampled_clouds(self, sub_grid_size): for cloud in natsorted(os.listdir(self.path)): cloud_name = cloud[:-4] full_ply_file = join(self.path, '{:s}.ply'.format(cloud_name)) full_data = read_ply(full_ply_file) full_xyz = np.vstack( (full_data['x'], full_data['y'], full_data['z'])).T full_colors = np.vstack( (full_data['red'], full_data['green'], full_data['blue'])).T full_labels = full_data['class'] xyz_min = np.amin( full_xyz, axis=0 )[0: 3] # TODO probar sin esto, se ha de haber entrenado sin (data prepare) full_xyz -= xyz_min sub_xyz, sub_colors, sub_labels = DP.grid_sub_sampling( full_xyz, full_colors, full_labels, sub_grid_size) sub_colors = sub_colors / 255.0 search_tree = KDTree(sub_xyz) proj_idx = np.squeeze( search_tree.query(full_xyz, return_distance=False)) proj_idx = proj_idx.astype(np.int32) self.input_trees['validation'] += [search_tree] self.input_colors['validation'] += [sub_colors] self.input_labels['validation'] += [sub_labels] self.input_names['validation'] += [cloud_name] self.input_full_xyz['validation'] += [full_xyz] self.val_proj += [proj_idx] self.val_labels += [full_labels]
pc = DP.load_pc_semantic3d(pc_path) pc_copy = np.array(pc) print(pc_copy.shape) print(pc_copy.min()) print(pc_copy.max()) # check if label exists label_path = pc_path[:-4] + '.labels' if exists(label_path): labels = DP.load_label_semantic3d(label_path) full_ply_path = join(original_pc_folder, file_name + '.ply') # Subsample to save space sub_points, sub_colors, sub_labels = DP.grid_sub_sampling( pc[:, :3].astype(np.float32), pc[:, 4:7].astype(np.uint8), labels, 0.01) print(np.array(sub_points).shape) print(np.array(sub_colors).shape) print(np.array(sub_labels).shape) print("sub_points min:" + str(sub_points.min())) print("sub_points max:" + str(sub_points.max())) sub_labels = np.squeeze(sub_labels) #Directory print("writing FULL ply files *****Start*****") write_ply(full_ply_path, (sub_points, sub_colors, sub_labels), ['x', 'y', 'z', 'red', 'green', 'blue', 'class']) print("writing FULL ply files *****End*****") # save sub_cloud and KDTree file
os.makedirs(pc_path_out) if not exists(pc_path_out) else None os.makedirs(KDTree_path_out) if not exists(KDTree_path_out) else None if int(seq_id) < 11: label_path = join(seq_path, 'labels') label_path_out = join(seq_path_out, 'labels') os.makedirs(label_path_out) if not exists(label_path_out) else None scan_list = np.sort(os.listdir(pc_path)) for scan_id in scan_list: print(scan_id) points = DP.load_pc_kitti(join(pc_path, scan_id)) labels = DP.load_label_kitti( join(label_path, str(scan_id[:-4]) + '.label'), remap_lut) sub_points, sub_labels = DP.grid_sub_sampling(points, labels=labels, grid_size=grid_size) search_tree = KDTree(sub_points) KDTree_save = join(KDTree_path_out, str(scan_id[:-4]) + '.pkl') np.save(join(pc_path_out, scan_id)[:-4], sub_points) np.save(join(label_path_out, scan_id)[:-4], sub_labels) with open(KDTree_save, 'wb') as f: pickle.dump(search_tree, f) if seq_id == '08': proj_path = join(seq_path_out, 'proj') os.makedirs(proj_path) if not exists(proj_path) else None proj_inds = np.squeeze( search_tree.query(points, return_distance=False)) proj_inds = proj_inds.astype(np.int32) proj_save = join(proj_path, str(scan_id[:-4]) + '_proj.pkl') with open(proj_save, 'wb') as f:
def convert_pc2plyandweaklabels(anno_path, save_path, sub_pc_folder, weak_label_folder, weak_label_ratio, sub_grid_size, gt_class, gt_class2label): """ Convert original dataset files (consiting of rooms) to ply file and weak labels. Physically, each room will generate several files, including raw_pc.ply, sub_pc.ply, sub_pc.pkl (for the kdtree), proj_idx.pkl (for each raw point's nearest neighbor in the sub_pc) and weak labels for raw and sub_pc, respectively ) :param anno_path: path to annotations. e.g. Area_1/office_2/Annotations/ :param save_path: path to save original point clouds (each line is XYZRGBL), e.g., xx.ply :return: None """ # save raw_cloud if not os.path.exists(save_path): data_list = [] # aggregate a room's instances into 1 pc for f in glob.glob(join(anno_path, '*.txt')): class_name = os.path.basename(f).split('_')[0] if class_name not in gt_class: # note: in some room there is 'staris' class.. class_name = 'clutter' pc = pd.read_csv(f, header=None, delim_whitespace=True).values labels = np.ones((pc.shape[0], 1)) * gt_class2label[class_name] data_list.append(np.concatenate([pc, labels], 1)) # Nx7 # translate the data by xyz_min--yc pc_label = np.concatenate(data_list, 0) # Nx7 as a np object xyz_min = np.amin(pc_label, axis=0)[0:3] pc_label[:, 0:3] -= xyz_min # manage data types and save in PLY format--yc xyz = pc_label[:, :3].astype(np.float32) colors = pc_label[:, 3:6].astype(np.uint8) labels = pc_label[:, 6].astype(np.uint8) write_ply(save_path, (xyz, colors, labels), ['x', 'y', 'z', 'red', 'green', 'blue', 'class']) else: # if existed then read this ply file to fill the data/xyz/colors/labels data = read_ply(save_path) # ply format: x,y,z,red,gree,blue,class xyz = np.vstack((data['x'], data['y'], data['z'])).T # (N',3), note the transpose symbol colors = np.vstack( (data['red'], data['green'], data['blue'])).T # (N',3), note the transpose symbol labels = data['class'] pc_label = np.concatenate( (xyz, colors, np.expand_dims(labels, axis=1)), axis=1) # (N,7) # save sub_cloud sub_ply_file = join(sub_pc_folder, save_path.split('/')[-1][:-4] + '.ply') if not os.path.exists(sub_ply_file): sub_xyz, sub_colors, sub_labels = DP.grid_sub_sampling( xyz, colors, labels, sub_grid_size) sub_colors = sub_colors / 255.0 write_ply(sub_ply_file, [sub_xyz, sub_colors, sub_labels], ['x', 'y', 'z', 'red', 'green', 'blue', 'class']) else: data = read_ply(sub_ply_file) # ply format: x,y,z,red,gree,blue,class sub_xyz = np.vstack((data['x'], data['y'], data['z'])).T # (N',3), note the transpose symbol sub_colors = np.vstack( (data['red'], data['green'], data['blue'])).T # (N',3), note the transpose symbol sub_labels = data['class'] # save KDTree for sub_pc kd_tree_file = join(sub_pc_folder, str(save_path.split('/')[-1][:-4]) + '_KDTree.pkl') if not os.path.exists(kd_tree_file): search_tree = KDTree(sub_xyz) with open(kd_tree_file, 'wb') as f: pickle.dump(search_tree, f) # save projection indcies for all raw points over the corresponding sub_pc proj_save = join(sub_pc_folder, str(save_path.split('/')[-1][:-4]) + '_proj.pkl') if not os.path.exists(proj_save): proj_idx = np.squeeze(search_tree.query(xyz, return_distance=False)) proj_idx = proj_idx.astype(np.int32) with open(proj_save, 'wb') as f: pickle.dump([proj_idx, labels], f) """ USED for weakly semantic segmentation - save raw pc's weak labels - save sub pc's weak labels """ # save raw pc's weak label mask weak_label_ply_file = join( weak_label_folder, save_path.split('/')[-1][:-4] + '_weak_label.ply') if not os.path.exists(weak_label_ply_file): # set weak points by randomly selecting weak_label_ratio*N points and denote them w. a mask num_cloud_points = pc_label.shape[0] weak_label_mask = np.zeros((num_cloud_points, 1), dtype=np.uint8) # BUG FIXED: fixed already; here, should set replace = True, otherwise a bug will be resulted selected_idx = np.random.choice(num_cloud_points, int(num_cloud_points * weak_label_ratio), replace=False) weak_label_mask[selected_idx, :] = 1 write_ply(weak_label_ply_file, (weak_label_mask, ), ['weak_mask']) else: data = read_ply( weak_label_ply_file) # ply format: x,y,z,red,gree,blue,class weak_label_mask = data['weak_mask'] # save sub pc's weak label mask weak_label_sub_file = join( weak_label_folder, save_path.split('/')[-1][:-4] + '_sub_weak_label.ply') if not os.path.exists(weak_label_sub_file): # HACK: the grid_sub_sampling is deterministic if the inputs are the same. So sub_xyz and sub_colors are the same when called 2nd time _, _, weak_label_sub_mask = DP.grid_sub_sampling( xyz, colors, weak_label_mask, sub_grid_size) write_ply(weak_label_sub_file, (weak_label_sub_mask, ), ['weak_mask'])
# check if it has already calculated if exists(join(sub_pc_folder, file_name + '_KDTree.pkl')): continue pc = DP.load_pc_semantic3d(pc_path) xyz_min = np.amin(pc, axis=0)[0:3] pc[:, 0:3] -= xyz_min print("Testing") full_ply_path = join(original_pc_folder, file_name + '.ply') write_ply(full_ply_path, (pc[:, :3].astype(np.float32)), ['x', 'y', 'z']) # save sub_cloud and KDTree file sub_xyz, sub_colors = DP.grid_sub_sampling(pc[:, :3].astype(np.float32), pc[:, :3].astype(np.uint8), grid_size=grid_size) #sub_colors = sub_colors / 255.0 sub_ply_file = join(sub_pc_folder, file_name + '.ply') write_ply(sub_ply_file, [sub_xyz], ['x', 'y', 'z']) labels = np.zeros(pc.shape[0], dtype=np.uint8) search_tree = KDTree(sub_xyz, leaf_size=50) kd_tree_file = join(sub_pc_folder, file_name + '_KDTree.pkl') with open(kd_tree_file, 'wb') as f: pickle.dump(search_tree, f) proj_idx = np.squeeze( search_tree.query(pc[:, :3].astype(np.float32), return_distance=False)) proj_idx = proj_idx.astype(np.int32) proj_save = join(sub_pc_folder, file_name + '_proj.pkl')
pc_label = np.concatenate(data_list, 0) xyz_min = np.amin( pc_label, axis=0 )[0: 3] # TODO si esto no se hace y se lee de ply, no hace falta guardar carpeta original pc_label[:, 0:3] -= xyz_min xyz = pc_label[:, :3].astype(np.float32) colors = pc_label[:, 3:6].astype(np.uint8) labels = pc_label[:, 6].astype(np.uint8) ply_file = os.path.join(path_orig, split, case + ".ply") write_ply(ply_file, (xyz, colors, labels), ['x', 'y', 'z', 'red', 'green', 'blue', 'class']) # save sub_cloud and KDTree file sub_xyz, sub_colors, sub_labels = DP.grid_sub_sampling( xyz, colors, labels, sub_grid_size) sub_colors = sub_colors / 255.0 sub_ply_file = os.path.join(path_out_sub, case + ".ply") write_ply(sub_ply_file, [sub_xyz, sub_colors, sub_labels], ['x', 'y', 'z', 'red', 'green', 'blue', 'class']) search_tree = KDTree(sub_xyz) kd_tree_file = os.path.join(path_out_sub, case + "_KDTree.pkl") with open(kd_tree_file, 'wb') as f: pickle.dump(search_tree, f) proj_idx = np.squeeze(search_tree.query(xyz, return_distance=False)) proj_idx = proj_idx.astype(np.int32) proj_save = os.path.join(path_out_sub, case + "_proj.pkl") with open(proj_save, 'wb') as f: pickle.dump([proj_idx, labels], f)