def export_pointcloud(vertices, out_file, as_text=True): assert (vertices.shape[1] == 3) vertices = vertices.astype(np.float32) vertices = np.ascontiguousarray(vertices) vector_dtype = [('x', 'f4'), ('y', 'f4'), ('z', 'f4')] vertices = vertices.view(dtype=vector_dtype).flatten() plyel = PlyElement.describe(vertices, 'vertex') plydata = PlyData([plyel], text=as_text) plydata.write(out_file)
def save_mesh(mesh, n): lists = [tuple(i) for i in mesh.positions] # positions_element = PlyElement.describe(, "vertex") positions_element = PlyElement.describe(np.array(lists, dtype=[("x", "f4"), ("y", "f4"), ("z", "f4")]), "vertex") faces = [(face,) for face in mesh.faces] faces_element = PlyElement.describe(np.array(faces, dtype=[("vertex_indices", "i4", (3,))]), "face") PlyData([positions_element, faces_element], text=True).write("progress" + str(n) + ".ply")
def write_ply_with_color(fname, coords, colors): from plyfile import PlyData, PlyElement vertex = np.array([ tuple(list(vert) + list(col[:3])) for vert, col in zip(coords, colors) ], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')]) el = PlyElement.describe(vertex, 'vertex') PlyData([el]).write(fname)
def write_ply_rgb(points, colors, filename, text=True): """ input: Nx3, write points to filename as PLY format. """ points = [(points[i, 0], points[i, 1], points[i, 2], colors[i, 0], colors[i, 1], colors[i, 2]) for i in range(points.shape[0])] vertex = np.array(points, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')]) el = PlyElement.describe(vertex, 'vertex') PlyData([el], text=text).write(filename)
def save_points(points, path): vertex = np.zeros(points.shape[0], dtype=([('x', 'f4'), ('y', 'f4'), ('z', 'f4')])) vertex.fill(255) vertex['x'] = points[:, 0] vertex['y'] = points[:, 1] vertex['z'] = points[:, 2] el = PlyElement.describe(vertex, 'vertex') PlyData([el], text=ascii).write(path)
def extract_object_collection(self): print("extracting ScanNet objects...") object_collection = {} for object_id in self.info["object2point"].keys(): vertex, oldpoint2newpoint = self._extract_vertex(object_id) face = self._extract_face(object_id, oldpoint2newpoint) object_collection[object_id] = PlyData([vertex, face]) return object_collection
def ply_write(mesh, file, **opts): vertices = np.array([tuple(p) for p in mesh.points], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) faces = np.array([(f, t) for f, t in zip(mesh.faces, mesh.tracks)], dtype=[('vertex_indices', 'u4', (3, )), ('group', 'u2')]) ev = PlyElement.describe(vertices, 'vertex') ef = PlyElement.describe(faces, 'face') PlyData([ev, ef], opts.get('text', False)).write(file)
def save_sparseCubes_2ply(vxl_mask_list, vxl_ijk_list, rgb_list, \ param, ply_filePath, normal_list=None): """ save sparse cube to ply file --------- inputs: vxl_mask_list[i]: np.bool (iN_voxels,) vxl_ijk_list[i]: np.uint8 (iN_voxels, 3) rgb_list[i]: np.uint8 (iN_voxels, 3) normal_list[i]: np.float16 (iN_voxels, 3) param: np.float32(N_nonempty_cubes, 4) ply_filePath: 'xxx.ply' outputs: save to .ply file """ vxl_mask_np = np.concatenate(vxl_mask_list, axis=0) N_voxels = vxl_mask_np.sum() vxl_ijk_np = np.vstack(vxl_ijk_list) rgb_np = np.vstack(rgb_list) if not vxl_mask_np.shape[0] == vxl_ijk_np.shape[0] == rgb_np.shape[0]: raise Warning('make sure # of voxels in each cube are consistent.') if normal_list is None: dt = np.dtype([('x', '<f4'), ('y', '<f4'), ('z', '<f4'), \ ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')]) else: dt = np.dtype([('x', '<f4'), ('y', '<f4'), ('z', '<f4'), \ ('nx', '<f4'), ('ny', '<f4'), ('nz', '<f4'), \ ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')]) normal_np = np.vstack(normal_list)[vxl_mask_np] saved_pts = np.zeros(shape=(N_voxels, ), dtype=dt) # calculate voxels' xyz xyz_list = [] for _cube, _select in enumerate(vxl_mask_list): resol = param[_cube]['resol'] xyz_list.append(vxl_ijk_list[_cube][_select] * resol + param[_cube]['xyz'][None, :]) # (iN, 3) + (1, 3) xyz_np = np.vstack(xyz_list) vxl_ijk_np, rgb_np = vxl_ijk_np[vxl_mask_np], rgb_np[vxl_mask_np] saved_pts['x'], saved_pts['y'], saved_pts[ 'z'] = xyz_np[:, 0], xyz_np[:, 1], xyz_np[:, 2] saved_pts['red'], saved_pts['green'], saved_pts[ 'blue'] = rgb_np[:, 0], rgb_np[:, 1], rgb_np[:, 2] if normal_list is not None: saved_pts['nx'], saved_pts['ny'], saved_pts[ 'nz'] = normal_np[:, 0], normal_np[:, 1], normal_np[:, 2] el_vertex = PlyElement.describe(saved_pts, 'vertex') outputFolder = '/'.join(ply_filePath.split('/')[:-1]) if not os.path.exists(outputFolder): os.makedirs(outputFolder) PlyData([el_vertex]).write(ply_filePath) print('saved ply file: {}'.format(ply_filePath)) return 1
def write_xyzL_ply(points, labels, filename, text=False): """ input: Nx3, write points to filename as PLY format. """ points = [(points[i, 0], points[i, 1], points[i, 2], labels[i]) for i in range(points.shape[0])] vertex = np.array(points, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('label', 'u1')]) el = PlyElement.describe(vertex, 'vertex', comments=['vertices']) PlyData([el], text=text).write(filename)
def export_ply(pc, filename): """ export .ply from a point cloud """ vertex = np.zeros(pc.shape[0], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) for i in range(pc.shape[0]): vertex[i] = (pc[i][0], pc[i][1], pc[i][2]) ply_out = PlyData([PlyElement.describe(vertex, 'vertex', comments=['vertices'])]) ply_out.write(filename)
def export_ply(pc, filename): vertex = np.zeros(pc.shape[0], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) for i in range(pc.shape[0]): vertex[i] = (pc[i][0], pc[i][1], pc[i][2]) ply_out = PlyData( [PlyElement.describe(vertex, 'vertex', comments=['vertices'])]) ply_filename = filename[:-4] + '.ply' ply_out.write(ply_filename)
def get_labels(filename,IDs): f = PlyData().read(filename) remapper = np.ones(150) * (-100) for i, x in enumerate(IDs): remapper[x] = i sem_labels = remapper[np.array(f.elements[0]['label'])] return sem_labels
def gen_mesh_ply(ply_fn, vertices0, vertex_idx, face_label=None, vertex_label=None, vertex_color=None, extra='label_color_default'): ''' ''' assert (int(face_label is None) + int(vertex_label is None) + int(vertex_color is None)) >=2, \ "choose one color method from three: {}, {}, {}".format(face_label, vertex_label, vertex_color) assert vertices0.shape[-1] == 3 vnpf = vertex_idx.shape[-1] assert np.min(vertex_idx) >= 0, "negative vertex_idx" vertices0 = np.reshape(vertices0, (-1, 3)) vertex_idx = np.reshape(vertex_idx, (-1, vnpf)) if vertex_label is not None: vertex_label = np.reshape(vertex_label, (-1)) if vertex_color is not None: vertex_color = np.reshape(vertex_color, (-1, 3)) num_vertex = vertices0.shape[0] assert np.max(vertex_idx) < num_vertex is_vertex_color = (vertex_label is not None) or (vertex_color is not None) if not is_vertex_color: vertex = np.zeros(shape=(num_vertex)).astype([('x', 'f8'), ('y', 'f8'), ('z', 'f8')]) else: if vertex_label is not None: vertex_color = np.take(color_dic.rgb_order, vertex_label, 0) assert vertex_color.shape[0] == num_vertex vertex = np.zeros(shape=(num_vertex)).astype([('x', 'f8'), ('y', 'f8'), ('z', 'f8'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')]) for i in range(vertices0.shape[0]): if not is_vertex_color: vertex[i] = (vertices0[i, 0], vertices0[i, 1], vertices0[i, 2]) else: vertex[i] = ( vertices0[i,0],vertices0[i,1],vertices0[i,2], \ vertex_color[i,0], vertex_color[i,1], vertex_color[i,2]) el_vertex = PlyElement.describe(vertex, 'vertex') if vnpf > 2: el_face = get_face_ele(vertex_idx, face_label, extra) else: el_face = get_edge_ele(vertex_idx, face_label, extra) dirname = os.path.dirname(ply_fn) if not os.path.exists(dirname): os.makedirs(dirname) PlyData([el_vertex, el_face], text=True).write(ply_fn) print('write %s ok' % (ply_fn))
def save_point_cloud(pcd, rgb, filename, binary=True): """Save an RGB point cloud as a PLY file. :paras @pcd: Nx3 matrix, the XYZ coordinates @rgb: NX3 matrix, the rgb colors for each 3D point """ assert pcd.shape[0] == rgb.shape[0] if rgb is None: gray_concat = np.tile(np.array([128], dtype=np.uint8), (pcd.shape[0], 3)) points_3d = np.hstack((pcd, gray_concat)) else: points_3d = np.hstack((pcd, rgb)) python_types = (float, float, float, int, int, int) npy_types = [('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')] if binary is True: # Format into NumPy structured array vertices = [] for row_idx in range(points_3d.shape[0]): cur_point = points_3d[row_idx] vertices.append( tuple( dtype(point) for dtype, point in zip(python_types, cur_point))) vertices_array = np.array(vertices, dtype=npy_types) el = PlyElement.describe(vertices_array, 'vertex') # Write PlyData([el]).write(filename) else: x = np.squeeze(points_3d[:, 0]) y = np.squeeze(points_3d[:, 1]) z = np.squeeze(points_3d[:, 2]) r = np.squeeze(points_3d[:, 3]) g = np.squeeze(points_3d[:, 4]) b = np.squeeze(points_3d[:, 5]) ply_head = 'ply\n' \ 'format ascii 1.0\n' \ 'element vertex %d\n' \ 'property float x\n' \ 'property float y\n' \ 'property float z\n' \ 'property uchar red\n' \ 'property uchar green\n' \ 'property uchar blue\n' \ 'end_header' % r.shape[0] # ---- Save ply data to disk np.savetxt(filename, np.column_stack((x, y, z, r, g, b)), fmt="%d %d %d %d %d %d", header=ply_head, comments='')
def write_ply_rgb(points, colors, filename, text=True, num_classes=None): """ Color (N,3) points with RGB colors (N,3) within range [0,255] as OBJ file """ colors = colors.astype(int) points = [(points[i, 0], points[i, 1], points[i, 2], colors[i, 0], colors[i, 1], colors[i, 2]) for i in range(points.shape[0])] vertex = np.array(points, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')]) el = PlyElement.describe(vertex, 'vertex', comments=['vertices']) PlyData([el], text=text).write(filename)
def save_ply(vert, face, fname): nf = len(face[0]) el1 = PlyElement.describe( np.array([(x[0], x[1], x[2]) for x in vert], dtype=[('x', 'f8'), ('y', 'f8'), ('z', 'f8')]), 'vertex') el2 = PlyElement.describe( np.array([([*x], 0) for x in face], dtype=[('vertex_indices', 'i4', (nf, )), ('red', 'u1')]), 'face') PlyData([el1, el2], text=True).write(fname)
def writePlyCloud(cloudpath, points, normals, colors, text=False): verts = np.concatenate((points.detach().cpu().numpy(), normals.detach().cpu().numpy(), (255*colors.clamp(0.0, 1.0)).detach().cpu().numpy()), axis=1) verts = [tuple(row) for row in verts] elV = PlyElement.describe(np.array(verts, dtype=[ ('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('nx', 'f4'), ('ny', 'f4'), ('nz', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')]), 'vertex') dirP = os.path.dirname(cloudpath) os.makedirs(dirP, exist_ok=True) PlyData([elV], text=text).write(cloudpath)
def renderPlyFile(XX, filename): if len(XX) > 0: points = np.array(zip(XX[:, 0].ravel(), XX[:, 1].ravel(), XX[:, 2].ravel()), dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) el = PlyElement.describe(points, 'vertex') PlyData([el]).write(filename) else: print("Nothing rendered into file '%s' because points set was empty" % filename)
def write_ply(save_path, points, text=True): """ save_path : path to save: '/yy/XX.ply' pt: point_cloud: size (N,3) """ points = [(points[i, 0], points[i, 1], points[i, 2]) for i in range(points.shape[0])] vertex = np.array(points, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) el = PlyElement.describe(vertex, 'vertex', comments=['vertices']) PlyData([el], text=text).write(save_path)
def write_ply(filename, xyz, rgb): """write into a ply file""" prop = [('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')] vertex_all = np.empty(len(xyz), dtype=prop) for i_prop in range(0, 3): vertex_all[prop[i_prop][0]] = xyz[:, i_prop] for i_prop in range(0, 3): vertex_all[prop[i_prop+3][0]] = rgb[:, i_prop] ply = PlyData([PlyElement.describe(vertex_all, 'vertex')], text=True) ply.write(filename)
def save_point_cloud(filename, xyz, rgb=None): if rgb is None: vertex = np.array([(xyz[k, 0], xyz[k, 1], xyz[k, 2]) for k in range(xyz.shape[0])], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) else: vertex = np.array([(xyz[k, 0], xyz[k, 1], xyz[k, 2], rgb[k, 0], rgb[k, 1], rgb[k, 2]) for k in range(xyz.shape[0])], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')]) # PlyData([PlyElement.describe(vertex, 'vertex')], text=True).write(filename) # from fairseq import pdb; pdb.set_trace() PlyData([PlyElement.describe(vertex, 'vertex')]).write(open(filename, 'wb'))
def scalar2ply(filename, xyz, scalar): """write a ply with an unisgned integer scalar field""" prop = [('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('scalar', 'f4')] vertex_all = np.empty(len(xyz), dtype=prop) for i in range(0, 3): vertex_all[prop[i][0]] = xyz[:, i] vertex_all[prop[3][0]] = scalar ply = PlyData([PlyElement.describe(vertex_all, 'vertex')], text=True) ply.write(filename)
def export_voxels(self, return_mesh=False): logger.info("exporting learned sparse voxels...") voxel_idx = torch.arange(self.keep.size(0), device=self.keep.device) voxel_idx = voxel_idx[self.keep.bool()] voxel_pts = self.points[self.keep.bool()] if not return_mesh: # HACK: we export the original voxel indices as "quality" in case for editing points = [ (voxel_pts[k, 0], voxel_pts[k, 1], voxel_pts[k, 2], voxel_idx[k]) for k in range(voxel_idx.size(0)) ] vertex = np.array(points, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('quality', 'f4')]) return PlyData([PlyElement.describe(vertex, 'vertex')]) else: # generate polygon for voxels center_coords, residual = discretize_points(voxel_pts, self.voxel_size / 2) offsets = torch.tensor([[-1,-1,-1],[-1,-1,1],[-1,1,-1],[1,-1,-1],[1,1,-1],[1,-1,1],[-1,1,1],[1,1,1]], device=center_coords.device) vertex_coords = center_coords[:, None, :] + offsets[None, :, :] vertex_points = vertex_coords.type_as(residual) * self.voxel_size / 2 + residual faceidxs = [[1,6,7,5],[7,6,2,4],[5,7,4,3],[1,0,2,6],[1,5,3,0],[0,3,4,2]] all_vertex_keys, all_vertex_idxs = {}, [] for i in range(vertex_coords.shape[0]): for j in range(8): key = " ".join(["{}".format(int(p)) for p in vertex_coords[i,j]]) if key not in all_vertex_keys: all_vertex_keys[key] = vertex_points[i,j] all_vertex_idxs += [key] all_vertex_dicts = {key: u for u, key in enumerate(all_vertex_idxs)} all_faces = torch.stack([torch.stack([vertex_coords[:, k] for k in f]) for f in faceidxs]).permute(2,0,1,3).reshape(-1,4,3) all_faces_keys = {} for l in range(all_faces.size(0)): key = " ".join(["{}".format(int(p)) for p in all_faces[l].sum(0) // 4]) if key not in all_faces_keys: all_faces_keys[key] = all_faces[l] vertex = np.array([tuple(all_vertex_keys[key].cpu().tolist()) for key in all_vertex_idxs], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) face = np.array([([all_vertex_dicts["{} {} {}".format(*b)] for b in a.cpu().tolist()],) for a in all_faces_keys.values()], dtype=[('vertex_indices', 'i4', (4,))]) return PlyData([PlyElement.describe(vertex, 'vertex'), PlyElement.describe(face, 'face')])
def pc_transform(read_file, pc_file, trans_matrix, downsample=True, write_output=False, out_path=None): if read_file: with open(pc_file, 'rb') as f: plydata = PlyData.read(f) dtype = plydata['vertex'].data.dtype #print('dtype: {}'.format(dtype)) data = np.array(plydata['vertex'].data.tolist()) else: data = pc_file assert isinstance(data, np.ndarray) data = np.array(data.tolist()) xyz = data[:, :3] xyz = np.concatenate([xyz, np.ones([xyz.shape[0], 1])], axis=1) transformed_xyz = np.matmul(trans_matrix, xyz.transpose([1, 0])).transpose([1, 0]) transformed_xyz = transformed_xyz[:, :3] normal_trans_mat = trans_matrix.copy() normal_trans_mat[:3, 3] = 0 surface_normal = data[:, 6:9] surface_normal = np.concatenate( [surface_normal, np.ones([xyz.shape[0], 1])], axis=1) transformed_sn = np.matmul(normal_trans_mat, surface_normal.transpose([1, 0])).transpose([1, 0]) transformed_sn = transformed_sn[:, :3] new_data = np.concatenate([transformed_xyz, data[:, 3:6], transformed_sn], axis=1) if downsample: new_data = [ new_data[i] for i in range(len(new_data)) if random.random() > 0.5 ] vertex = np.array([tuple(x) for x in new_data], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1'), ('nx', 'f4'), ('ny', 'f4'), ('nz', 'f4')]) vertex_el = PlyElement.describe(vertex, 'vertex') if write_output: assert out_path PlyData([vertex_el]).write(out_path) # write the new ply file return vertex
def geof2ply(filename, xyz, geof): """write a ply with colors corresponding to geometric features""" color = np.array(255 * geof[:, [0, 1, 3]], dtype='uint8') prop = [('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')] vertex_all = np.empty(len(xyz), dtype=prop) for i in range(0, 3): vertex_all[prop[i][0]] = xyz[:, i] for i in range(0, 3): vertex_all[prop[i+3][0]] = color[:, i] ply = PlyData([PlyElement.describe(vertex_all, 'vertex')], text=True) ply.write(filename)
def save_point_cloud(point_cloud, path): dt = [('x', '<f4'), ('y', '<f4'), ('z', '<f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')] vertex = np.array(np.zeros(point_cloud.shape[0]), dtype=dt) vertex['x'] = point_cloud[:, 0] vertex['y'] = point_cloud[:, 1] vertex['z'] = point_cloud[:, 2] vertex['red'] = point_cloud[:, 3] vertex['green'] = point_cloud[:, 4] vertex['blue'] = point_cloud[:, 5] el = PlyElement.describe(vertex, 'vertex') PlyData([el]).write(path)
def save_ply(V,T,filename): if(V.shape[1]==2): Vt = np.zeros((V.shape[0],3)) Vt[:,0:2] = V V = Vt vertex = np.array(totuple(V),dtype=[('x', 'f4'), ('y', 'f4'),('z', 'f4')]) face = np.array([ tuple([i]) for i in T],dtype=[('vertex_indices', 'i4', (3,))]) el1 = PlyElement.describe(vertex, 'vertex') el2 = PlyElement.describe(face, 'face') PlyData([el1,el2]).write(filename)
def save_ply(self, filename): vertex = np.array([tuple(i) for i in self.v], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) face = np.array([(tuple(i), 255, 255, 255) for i in self.f], dtype=[('vertex_indices', 'i4', (3, )), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')]) el = PlyElement.describe(vertex, 'vertex') el2 = PlyElement.describe(face, 'face') plydata = PlyData([el, el2]) plydata.write(filename)
def export_ply(file_name, vertices, normals=None, scalar=None): points = PlyElement.describe(format_np_array(vertices), 'points') elements = [points] if normals is not None: normals = PlyElement.describe(format_np_array(normals), 'normals') elements.append(normals) if scalar is not None: scalar = PlyElement.describe(format_np_array_scalar(scalar), 'scalar') elements.append(scalar) PlyData(elements).write(file_name)
def ply_write(mesh, file, **opts): vertices = np.array(mesh.points, copy=False).astype( np.dtype([('x', 'f4'), ('y', 'f4'), ('z', 'f4')])) faces = np.empty(len(mesh.faces), dtype=[('vertex_indices', 'u4', (3, )), ('group', 'u2')]) faces['vertex_indices'] = typedlist_to_numpy(mesh.faces, 'u4') faces['group'] = typedlist_to_numpy(mesh.tracks, 'u4') ev = PlyElement.describe(vertices, 'vertex') ef = PlyElement.describe(faces, 'face') PlyData([ev, ef], opts.get('text', False)).write(file)