def main(): unit = 'mm' # get mesh list mesh_folder_dir = "/home/yumi/Datas/mesh/01/o3d_vis" mesh_list = os.listdir(mesh_folder_dir) # print(mesh_list) # suffix = '.stl' for mesh_file in mesh_list: # load mesh and visualize mesh_path = os.path.join(mesh_folder_dir, mesh_file) mesh_path_string = str(mesh_path) if ".stl" in mesh_path_string: mesh = trimesh.load_mesh(mesh_path) mesh.export(mesh_path.replace('.stl', '.ply')) mesh_o3d = o3d.read_triangle_mesh(mesh_path.replace('.stl', '.ply')) else: mesh_o3d = o3d.read_triangle_mesh(mesh_path) print("mesh name:{}".format(mesh_file)) # unit conversion (m -> mm) max_bound = mesh_o3d.get_max_bound() if ((unit == 'mm') & (max_bound[0] < 1)): R = np.identity(3) T = np.zeros(3) Z = [1000.0, 1000.0, 1000.0] H = t3d.affines.compose(T, R, Z) mesh_o3d.transform(H) if ((unit == 'cm') & (max_bound[0] < 100)): R = np.identity(3) T = np.zeros(3) Z = [100.0, 100.0, 100.0] H = t3d.affines.compose(T, R, Z) mesh_o3d.transform(H) # draw object's bounding box new_mesh_bound = mesh_o3d.get_max_bound() color = [1, 0, 0] object_bbox = bounding_box(new_mesh_bound, color) # visualization, x, y, z axis will be rendered as red, green, and blue base_coordinate = o3d.create_mesh_coordinate_frame(size=50) # reference bbox reference_bound = [50, 50, 50] reference_color = [0, 1, 0] reference_bbox = bounding_box(reference_bound, reference_color) o3d.visualization.draw_geometries([reference_bbox, mesh_o3d, base_coordinate, object_bbox])
def main(): system('') # Enable VT100 Emulation for colors in Windows # color_cube.py header modified so that Open3D can read the colors (eg. 'diffuse_red' -> 'r') mesh = open3d.read_triangle_mesh('input/extra/color_cube_mod.ply') he_mesh = HalfEdgeDS(mesh) print('Displaying Original Mesh...') print('Vertices:\x1B[32m', len(he_mesh.vertices), '\x1B[0mEgdes:\x1B[32m', int(len(he_mesh.halfedges) / 2), '\x1B[0mFaces:\x1B[32m', len(he_mesh.faces), '\x1B[0m') mesh.compute_vertex_normals() open3d.draw_geometries([mesh]) for i in range(5): print('Deleting random edge.') deletion_index = randint(0, len(he_mesh.halfedges) - 1) delete_halfedge(he_mesh, he_mesh.halfedges[deletion_index]) print('Displaying Mesh with {} random edge(s) deleted...'.format(i + 1)) print('Vertices:\x1B[32m', len(he_mesh.vertices), '\x1B[0mEgdes:\x1B[32m', int(len(he_mesh.halfedges) / 2), '\x1B[0mFaces:\x1B[32m', len(he_mesh.faces), '\x1B[0m') mesh = he_mesh.convert_to_IFS() mesh.compute_vertex_normals() if (i == 0): open3d.write_triangle_mesh('output/hw3p5a.ply', mesh) open3d.draw_geometries([mesh])
def show_object_mesh(base_dir, filename_suffix='', sigmoid_a=0.05, output_filename='test.png'): object_name_filename = osp.join(base_dir, 'object_name.txt') with open(object_name_filename, 'r') as f: object_name = f.readline().strip() mesh_filename = osp.join(base_dir, 'thermal_images', '{:s}_textured{:s}.ply'.format(object_name, filename_suffix)) m = open3d.read_triangle_mesh(mesh_filename) if not m.has_vertex_normals(): m.compute_vertex_normals() m.compute_triangle_normals() # apply colormap colors = np.asarray(m.vertex_colors)[:, 0] colors = texture_proc(colors, a=sigmoid_a, invert=('full14' in mesh_filename)) m.vertex_colors = open3d.Vector3dVector(colors) show_object_mesh.im_count = 0 show_object_mesh.output_filename_template = '{:s}_{:s}.png'.\ format(output_filename.split('.')[0], '{:02d}') def imsave_cb(vis): glb = show_object_mesh im = vis.capture_screen_float_buffer(False) im_filename = glb.output_filename_template.format(glb.im_count) plt.imsave(im_filename, np.asarray(im), dpi=1) print('Saved {:s}'.format(im_filename)) glb.im_count = glb.im_count + 1 return False open3d.draw_geometries_with_key_callbacks([m], {ord("."): imsave_cb})
def ply2xyz(self, FN): fileDir = "C:/Users/Ozguc Capunaman/Documents/GitHub/InteractiveDigitalFabrication/sessions/" + self._session srcDir = fileDir + "/" + FN + ".ply" ply = open3d.read_triangle_mesh(srcDir) xyz = open3d.PointCloud() srcDir = fileDir + "/" + FN xyz.points = ply.vertices targetDir = fileDir + "/" + FN + ".xyz" open3d.write_point_cloud(targetDir, xyz)
def ply2xyz(filename="", srcPath="../ply/", targetPath="../xyz/"): srcDir = srcPath + filename + ".ply" ply = open3d.read_triangle_mesh(srcDir) xyz = open3d.PointCloud() xyz.points = ply.vertices targetDir = targetPath + filename + ".xyz" print(targetDir) open3d.write_point_cloud(targetDir, xyz) return xyz
def main(): system('') # Enable VT100 Emulation for colors in Windows ply_meshes = [ 'input/color_cube.ply', 'input/mobius5k-surface.ply', 'input/bunny.ply' ] for file in ply_meshes: he_mesh = HalfEdgeDS(open3d.read_triangle_mesh(file)) print('Converted \'{}\' to'.format(file), he_mesh) print('Is mesh from file \'{}\' watertight? \x1B[32m{}\x1B[0m'.format( file, is_watertight(he_mesh)))
def main(): system('') # Enable VT100 Emulation for colors in Windows mesh = open3d.read_triangle_mesh('input/Armadillo.ply') print('IFS Mesh:\x1B[32m', mesh, '\x1B[0m') print('Converting to Half-Edge Data Structure...') he_mesh = mesh_io.HalfEdgeDS(mesh) print('Converted Mesh:\x1B[32m', he_mesh, '\x1B[0m') print('Reverting to IFS...') mesh = he_mesh.convert_to_IFS() mesh.compute_vertex_normals() mesh.paint_uniform_color([1, 0.706, 0]) print('Reverted Mesh:\x1B[32m', mesh, '\x1B[0m') open3d.draw_geometries([mesh])
def main(): # compare_neighbors_manually() # mesh = open3d.read_triangle_mesh('input/extra/color_cube_mod.ply') mesh = open3d.read_triangle_mesh('input/Armadillo.ply') print_wo_nl('Converting to Half-Edge Data Structure...') he_mesh = HalfEdgeDS(mesh) n = 10 print_wo_nl('Done.\nTesting for {} vertices...'.format(n)) result = True for _ in range(n): if (test_find_neighbors(mesh, he_mesh) == False): result = False break print('Done.\nAll neighbors found for', n, 'vertices?', result)
def transfer_meshes(instructions, sessions, include_objects, dest_host, dest_user, dest_dir): logger = logging.getLogger(__name__) if instructions is None: logger.error('No instructions specified') return for instruction in instructions: data_dirs = getattr(dataset_utils, '{:s}_data_dirs'.format(instruction)) if sessions is None: sessions = [ '{:d}'.format(idx + 1) for idx in range(len(data_dirs)) ] with paramiko.SSHClient() as ssh: ssh.load_system_host_keys() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname=dest_host, username=dest_user) with SCPClient(ssh.get_transport(), socket_timeout=20) as scp: for session_id in sessions: session_name = 'full{:s}_{:s}'.format( session_id, instruction) logger.info('Session {:s}'.format(session_name)) idx = int(session_id) - 1 mesh_filenames = dataset_utils.get_session_mesh_filenames( session_name, data_dirs[idx]) for object_name, mesh_filename in mesh_filenames.items(): if include_objects is not None: if object_name not in include_objects: continue m = open3d.read_triangle_mesh(mesh_filename) m.compute_vertex_normals() m.compute_triangle_normals() colors = np.asarray(m.vertex_colors)[:, 0] colors = texture_proc(colors, invert=('full14' in session_name)) m.vertex_colors = open3d.Vector3dVector(colors) open3d.write_triangle_mesh( '/tmp/tmp_contactdb_mesh.ply', m) dest_filename = osp.join( dest_dir, 'meshes', '{:s}_{:s}.ply'.format(session_name, object_name)) scp.put('/tmp/tmp_contactdb_mesh.ply', dest_filename) print('Written {:s}'.format(dest_filename)) time.sleep(1)
def compare_neighbors_manually(): mesh = open3d.read_triangle_mesh('input/extra/icosahedron.ply') for i in range(len(mesh.vertices)): neighbors = set() for tri in np.asarray(mesh.triangles): if i in tri: neighbors.update(tri) print(i, neighbors) print('') he_mesh = HalfEdgeDS(mesh) for vertex in he_mesh.vertices: neighbors = find_neighboring_vertices(vertex) nvi = [] for n in neighbors: nvi.append(n.index) print(vertex.index, nvi)
def main(): # mesh = open3d.read_triangle_mesh('input/extra/icosahedron.ply') # Every edge has the same length -> Output shape = Input shape mesh = open3d.read_triangle_mesh('input/extra/color_cube_mod.ply') # mesh = open3d.read_triangle_mesh('input/Armadillo.ply') mesh.paint_uniform_color([0.428, 0.428, 0.428]) mesh.compute_vertex_normals() print('Displaying Original Mesh.') open3d.draw_geometries([mesh]) print_alt('Converting to Half-Edge Data Structure...') he_mesh = HalfEdgeDS(mesh) print_alt('Done.\nSmoothing Mesh...') smoothen_mesh(he_mesh) print('Done.\nDisplaying Smoothened Mesh.') mesh = he_mesh.convert_to_IFS() mesh.compute_vertex_normals() open3d.draw_geometries([mesh]) open3d.write_triangle_mesh('output/hw3p6.ply', mesh)
def quadric_error_metric(curr_file_path, ratio, old_vertices): os.system(f"tridecimator " f"{curr_file_path} {curr_file_path} {ratio} -On -C > /dev/null") mesh = open3d.read_triangle_mesh(curr_file_path) if not mesh.has_vertices(): raise QEMError('no vertices left') coords = np.asarray(mesh.vertices) edges_list = edges_from_faces(np.asarray(mesh.triangles)) edge_out = [] for key, group in enumerate(edges_list): for elem in group: edge_out.append([key, elem]) reverse_trace = csv2npy(curr_file_path.replace('.ply', '.csv'), old_vertices=old_vertices, new_vertices=coords) return coords, edge_out, reverse_trace
def display_surface_normals(filename, size): mesh = open3d.read_triangle_mesh(filename) mesh.paint_uniform_color([0, 0, 0.353]) vertices = np.asarray(mesh.vertices) triangles = vertices[np.array(mesh.triangles)] # calculate normals normal_lines = [] for tri in triangles: u = tri[1] - tri[0] v = tri[2] - tri[0] normal = normalize(np.cross(u, v), size) center = (tri[0] + tri[1] + tri[2]) / 3 normal_lines.append(center) normal_lines.append(center + normal) lines = [[i, i + 1] for i in range(0, len(normal_lines), 2)] colors = [[1, 0, 0] for i in range(len(lines))] line_set = open3d.LineSet() line_set.points = open3d.Vector3dVector(normal_lines) line_set.lines = open3d.Vector2iVector(lines) line_set.colors = open3d.Vector3dVector(colors) open3d.draw_geometries([mesh, line_set])
def main(): system('') # Enable VT100 Emulation for colors in Windows # bunny modified to invert surface orientation of bunny.ply he_mesh = HalfEdgeDS(open3d.read_triangle_mesh('input/extra/bunny_meshlab.ply')) fill_mesh_holes(he_mesh) print('Displaying Original Mesh (after filling any holes)...') print('Vertices:\x1B[32m', len(he_mesh.vertices), '\x1B[0mEgdes:\x1B[32m', int(len(he_mesh.halfedges)/2), '\x1B[0mFaces:\x1B[32m', len(he_mesh.faces), '\x1B[0m') mesh = he_mesh.convert_to_IFS() mesh.compute_vertex_normals() mesh.paint_uniform_color([0.428, 0.428, 0.428]) open3d.draw_geometries([mesh]) for i in range(1000): delete_halfedge(he_mesh, he_mesh.halfedges[200]) print('Displaying Mesh with first x edges deleted...') print('Vertices:\x1B[32m', len(he_mesh.vertices), '\x1B[0mEgdes:\x1B[32m', int(len(he_mesh.halfedges)/2), '\x1B[0mFaces:\x1B[32m', len(he_mesh.faces), '\x1B[0m') mesh = he_mesh.convert_to_IFS() mesh.compute_vertex_normals() open3d.draw_geometries([mesh])
def main(): system('') # Enable VT100 Emulation for colors in Windows he_mesh = HalfEdgeDS( open3d.read_triangle_mesh('input/extra/color_cube_w_holes_mod.ply')) # he_mesh = HalfEdgeDS(IndexedFaceSet('input/extra/triangle.obj').get_mesh()) # he_mesh = HalfEdgeDS(open3d.read_triangle_mesh('input/extra/bunny_meshlab.ply')) holes = find_holes(he_mesh) print('Finding holes...') print('Holes found:\x1B[32m', len(holes), '\x1B[0m') hole_sizes = [len(hole) for hole in holes] print(' Sizes of holes found:\x1B[32m', hole_sizes, '\x1B[0m') mesh = he_mesh.convert_to_IFS() mesh.compute_vertex_normals() open3d.draw_geometries([mesh]) print('Filling holes...') fill_holes(he_mesh, holes) print('Holes yet to be filled:\x1B[32m', len(find_holes(he_mesh)), '\x1B[0m') print('Is filled mesh watertight?\x1B[32m', is_watertight(he_mesh), '\x1B[0m') mesh = he_mesh.convert_to_IFS() mesh.compute_vertex_normals() open3d.draw_geometries([mesh])
def mesh2pcd(mesh): if mesh.compute_vertex_normals() is False: mesh.compute_vertex_normals() pcd = open3d.PointCloud() pcd.points = mesh.vertices pcd.normals = mesh.vertex_normals return pcd # ====================================================================================================================== if __name__ == "__main__": tfile = os.path.join(dirs.inpdir, 'open3d/110920150452_new.ply') mesh = open3d.read_triangle_mesh(tfile) target = mesh2pcd(mesh) sfile = os.path.join(dirs.inpdir, 'open3d/mean_face.ply') mesh = open3d.read_triangle_mesh(sfile) source = mesh2pcd(mesh) open3d.draw_geometries([target]) open3d.draw_geometries([source]) trans_init = np.asarray([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) draw_registration_result(source, target, trans_init)
def process_frame(file_path: str, global_params: dict = None): premapping = global_params['mapping'] original_mesh = open3d.read_triangle_mesh(file_path) original_mesh.compute_vertex_normals() if args.train: # create train/val dataset if args.dataset in ['scannet']: labels_file_path = file_path.replace('.ply', '.labels.ply') vertex_labels = np.asarray( PlyData.read(labels_file_path)['vertex']['label']) elif args.dataset in ['s3dis']: labels_file_path = file_path.replace('.ply', '.labels.npy') vertex_labels = np.load(labels_file_path) elif args.dataset in ['matterport']: mapped_labels = premapping[PlyData.read(file_path)['face'] ['category_id']] mapped_labels[np.logical_not( np.isin(mapped_labels, MATTERPORT_ALLOWED_NYU_CLASSES))] = 0 vertices = np.asarray(original_mesh.vertices) triangles = np.asarray(original_mesh.triangles) remapped_labels = MATTERPORT_CLASS_REMAP[mapped_labels].astype(int) vertex_labels = np.zeros((vertices.shape[0], 22), dtype=np.int) # in matterport, the labels are given for each face and not for each vertex for row_id in range(triangles.shape[0]): for i in range(3): vertex_labels[triangles[row_id][i], remapped_labels[row_id]] += 1 vertex_labels = np.argmax(vertex_labels, axis=1) original_vertices = np.column_stack( (np.asarray(original_mesh.vertices), np.asarray(original_mesh.vertex_colors), np.asarray(original_mesh.vertex_normals), vertex_labels)) if args.dataset in ['scannet']: # FIX: THREE MESHES HAVE CORRUPTED LABEL IDS class_ids = original_vertices[:, -1].astype(int) class_ids[class_ids > 40] = 0 original_vertices[:, -1] = SCANNET_CLASS_REMAP[class_ids] else: # create test dataset (labels are not given here!) # this can only be done with scannet assert args.dataset in ['scannet'] original_vertices = np.column_stack( (np.asarray(original_mesh.vertices), np.asarray(original_mesh.vertex_colors), np.asarray(original_mesh.vertex_normals))) # store the number of vertices in order to generate dummy placeholders while evaluating on the test set s_path = file_path.replace('.ply', '_size.txt') if not os.path.isfile(s_path): with open(s_path, 'w') as s_file: s_file.write(f"{original_vertices.shape[0]}") if args.dataset in ['scannet']: subfolder = f"{file_path.split('/')[-2]}" curr_dir = f"{args.out_path}{subfolder}" elif args.dataset in ['matterport']: subfolder = f"{file_path.split('/')[-3]}_{file_path.split('/')[-1].replace('.ply', '')}" curr_dir = f"{args.out_path}{subfolder}" elif args.dataset in ['s3dis']: subfolder = f"{file_path.split('/')[-3]}_{file_path.split('/')[-2]}" curr_dir = f"{args.out_path}{subfolder}" clear_folder(f"{curr_dir}/") coords = [] edges_list = [] edge_output = [] traces = [] curr_mesh = original_mesh curr_vertices = np.asarray(curr_mesh.vertices) edge_list_0 = edges_from_faces(np.asarray(curr_mesh.triangles)) coords.append(curr_vertices) edges_list.append(edge_list_0) edge_output_0 = [] for key, group in enumerate(edge_list_0): for elem in group: edge_output_0.append([key, elem]) edge_output.append(np.array(edge_output_0)) if not args.vertex_clustering: # put current mesh in the working directory curr_mesh_path = f"{curr_dir}/curr_mesh.ply" open3d.io.write_triangle_mesh(curr_mesh_path, curr_mesh) for level in range(len(args.level_params)): if args.vertex_clustering: coords_l, trace_scatter, edge_list_l, edge_output_l = \ vertex_clustering( coords[-1], edges_list[-1], float(args.level_params[level])) else: if not args.level_params[level].isdigit(): # before using QEM apply Vertex Clustering with ensures triangular mesh # TODO no absolute paths! os.system( f"trimesh_clustering " f"{curr_mesh_path} {curr_mesh_path} -s {args.level_params[level]} > /dev/null" ) curr_mesh = open3d.io.read_triangle_mesh(curr_mesh_path) curr_mesh.compute_vertex_normals() coords_l = np.asarray(curr_mesh.vertices) edge_list_l = edges_from_faces(np.asarray(curr_mesh.triangles)) edge_output_0 = [] for key, group in enumerate(edge_list_l): for elem in group: edge_output_0.append([key, elem]) edge_output_l = edge_output_0 vh_ball_tree = BallTree(coords_l[:, :3]) vh_trace = vh_ball_tree.query(np.asarray(coords[0][:, :3]), k=1)[1].flatten() trace_scatter = vh_trace else: coords_l, edge_output_l, trace_scatter = \ quadric_error_metric(curr_mesh_path, int(args.level_params[level]), old_vertices=coords[-1]) edge_list_l = None coords.append(coords_l) traces.append(trace_scatter) edges_list.append(edge_list_l) edge_output.append(np.array(edge_output_l)) colors_labels = get_color_and_labels(original_vertices, coords) coords_color_labels = [] for i in range(len(coords)): coords_color_labels.append( np.column_stack((coords[i], colors_labels[i]))) clear_folder(f"{curr_dir}/") coords_color_labels = [ torch.from_numpy(coords_color_labels[i]) for i in range(len(coords_color_labels)) ] pt_data = {} if args.train: vertices = [coords_color_labels[1][:, :-1].float()] vertices.extend([ coords_color_labels[i][:, :3].float() for i in range(2, len(coords_color_labels)) ]) labels = coords_color_labels[0][:, -1].long() pt_data['vertices'] = vertices pt_data['labels'] = labels else: vertices = [coords_color_labels[1].float()] vertices.extend([ coords_color_labels[i][:, :3].float() for i in range(2, len(coords_color_labels)) ]) pt_data['vertices'] = vertices pt_data['edges'] = [ torch.from_numpy(edge_output[i]).long() for i in range(1, len(edge_output)) ] pt_data['traces'] = [torch.from_numpy(x).long() for x in traces] torch.save(pt_data, f"{curr_dir}.pt") # DELETE EMPTY FOLDER shutil.rmtree(f"{curr_dir}/")
import open3d as o3d def draw_geometries_with_back_face(geometries): visualizer = o3d.Visualizer() visualizer.create_window() render_option = visualizer.get_render_option() render_option.mesh_show_back_face = True for geometry in geometries: visualizer.add_geometry(geometry) visualizer.run() visualizer.destroy_window() if __name__ == "__main__": mesh = o3d.read_triangle_mesh("../../TestData/sphere.ply") mesh = o3d.crop_triangle_mesh(mesh, [-1, -1, -1], [1, 0.6, 1]) mesh.purge() mesh = o3d.create_half_edge_mesh_from_mesh(mesh) mesh.compute_vertex_normals() num_vertices = len(mesh.vertices) draw_geometries_with_back_face([mesh]) # Find a boundary vertex boundaries = mesh.get_boundaries() assert len(boundaries) == 1 boundary_vertices = boundaries[0] # Colorize boundary vertices vertex_colors = 0.75 * np.ones((num_vertices, 3)) vertex_colors[boundary_vertices, :] = np.array([1, 0, 0])
def map_texture(object_name, session_name, base_dir, models_dir, debug_mode=False, show_textured_mesh=False, depth_thresh_for_visibility=1e-2, depth_thresh_for_discontinuity=0.035, max_vertex_normal_angle=70, real_depth_maps=False): data_dir = osp.join(base_dir, session_name, object_name) try: with open(osp.join(data_dir, 'object_name.txt'), 'r') as f: object_name = f.readline().rstrip() except IOError: print('{:s} does not have object_name.txt, skipping'.format(data_dir)) return # read mesh file mesh_filename = osp.join(models_dir, '{:s}.ply'.format(object_name)) mesh = open3d.read_triangle_mesh(mesh_filename) if not mesh.has_vertex_normals(): mesh.compute_vertex_normals() # names of views rgb_im_dir = osp.join(data_dir, 'thermal_images') pose_dir = osp.join(data_dir, 'poses') names = [] for filename in os.listdir(pose_dir): if '.txt' not in filename: continue if 'camera_pose' not in filename: continue name = '_'.join(filename.split('.')[0].split('_')[2:]) names.append(name) names = sorted(names) # camera extrinsics Ts = [] for name in names: filename = osp.join(pose_dir, 'camera_pose_{:s}.txt'.format(name)) T = np.eye(4) with open(filename, 'r') as f: f.readline() T[0, 3] = float(f.readline().strip()) T[1, 3] = float(f.readline().strip()) T[2, 3] = float(f.readline().strip()) f.readline() f.readline() T[0, :3] = [float(v) for v in f.readline().strip().split()] T[1, :3] = [float(v) for v in f.readline().strip().split()] T[2, :3] = [float(v) for v in f.readline().strip().split()] Ts.append(np.linalg.inv(T)) # RGB images rgb_ims = [] im_intensities = [] for name in names: rgb_im = open3d.read_image(osp.join(rgb_im_dir, '{:s}.png'.format(name))) rgb_im = np.asarray(rgb_im) rgb_ims.append(rgb_im) im_shape = rgb_im.shape intensity = rgb_im[:200, :200, 0].mean() im_intensities.append(intensity) target_intensity = np.mean(im_intensities) for i, rgb_im in enumerate(rgb_ims): rgb_im = rgb_im * target_intensity / im_intensities[i] rgb_im = np.clip(rgb_im, a_min=0, a_max=255) rgb_ims[i] = open3d.Image(rgb_im.astype(np.uint8)) # camera intrinsic cinfo_filename = cinfo_manager.getPackageFileName( 'package://contactdb_utils/calibrations/boson.yaml') cinfo = cinfo_manager.loadCalibrationFile(cinfo_filename, 'boson') h_scaling = float(im_shape[0]) / cinfo.height w_scaling = float(im_shape[1]) / cinfo.width K = np.asarray(cinfo.K) K[0] *= w_scaling K[2] *= w_scaling K[4] *= h_scaling K[5] *= h_scaling K = K.reshape((3,3)) intrinsic = open3d.PinholeCameraIntrinsic(im_shape[1], im_shape[0], K[0,0], K[1,1], K[0,2], K[1,2]) if real_depth_maps: # use registered Kinect depthmaps depth_im_dir = osp.join(data_dir, 'depth_images') depth_ims = [] for name in names: depth_im_filename = osp.join(depth_im_dir, '{:s}.png'.format(name)) depth_im = open3d.read_image(depth_im_filename) depth_im = np.uint16(fill_holes(depth_im)) depth_ims.append(depth_im) else: # create depth maps by rendering depth_ims = render_depth_maps(mesh_filename, intrinsic, Ts) # create RGB-D images rgbds = [] for depth_im, rgb_im, T in zip(depth_ims, rgb_ims, Ts): depth_im = open3d.Image(depth_im) rgbds.append(open3d.create_rgbd_image_from_color_and_depth(rgb_im, depth_im, convert_rgb_to_intensity=False)) if debug_mode: pc = open3d.create_point_cloud_from_rgbd_image(rgbds[-1], intrinsic) tmesh = copy(mesh) tmesh.transform(T) geoms = [pc] if show_textured_mesh: geoms.append(tmesh) open3d.draw_geometries(geoms) # create trajectory for texture mapping traj = open3d.PinholeCameraTrajectory() traj.extrinsic = open3d.Matrix4dVector(np.asarray(Ts)) traj.intrinsic = intrinsic # do texture mapping! option = open3d.ColorMapOptmizationOption() option.maximum_iteration = 300 option.depth_threshold_for_visiblity_check = depth_thresh_for_visibility option.depth_threshold_for_discontinuity_check = \ depth_thresh_for_discontinuity option.half_dilation_kernel_size_for_discontinuity_map = 0 option.max_angle_vertex_normal_camera_ray = max_vertex_normal_angle open3d.color_map_optimization(mesh, rgbds, traj, option) if not debug_mode: # write result as a PLY file mesh_filename = osp.join(data_dir, 'thermal_images', '{:s}_textured.ply'.format(object_name)) open3d.write_triangle_mesh(mesh_filename, mesh) print('Written {:s}'.format(mesh_filename)) if show_textured_mesh: show_object_mesh(data_dir)
def main(): mesh = o3d.read_triangle_mesh("example.ply") custom_draw_geometry_with_view_tracking(mesh)
def __call__(self, vis): global state # Do nothing if self.key == 0: pass # Dump current output window elif self.key == ord('X'): args.dump_dir.mkdir(exist_ok=True) pascal_az = (int(state['angle_z']) + 90) % 360 pascal_el = 90 - int(state['angle_y']) rad = int(state['radius']) d_id = state['dump_id'] id_str = f'{d_id:03d}_el_{pascal_el:03d}_az_{pascal_az:03d}_rad_{rad:03d}' dump_image_path = str(args.dump_dir / f'{id_str}.png') cv2.imwrite(dump_image_path, state['dump_image']) print(f'Saved {dump_image_path}.') state['dump_id'] += 1 # Override open3D reset elif self.key == ord('R'): pass # Rotation around Y axis elif self.key == ord('F'): state['angle_y'] += 5 elif self.key == ord('D'): state['angle_y'] -= 5 # Rotation around Z axis elif self.key == ord('S'): state['angle_z'] += 5 elif self.key == ord('A'): state['angle_z'] -= 5 # Distance from origin (+) elif self.key == ord('H'): state['radius'] += 0.05 # Distance from origin (-) elif self.key == ord('G'): state['radius'] -= 0.05 # Next dataset example elif self.key == ord(' '): state['texture_src'] = state['dataset'][state['dataset_index']] state['dataset_index'] += 1 # Next CAD model elif self.key == ord('N'): state['cad_idx'] += 1 if state['cad_idx'] == 10: state['cad_idx'] = 0 # Update model and 3D keypoints cad_idx = state['cad_idx'] model_path = args.CAD_root / f'pascal_{state["pascal_class"]}_cad_{cad_idx:03d}.ply' # Load 3D keypoints for current model yaml_file = model_path.parent / (model_path.stem + '.yaml') state['kpoints_3d'] = load_yaml_file(yaml_file)['kpoints_3d'] mesh = o3d.read_triangle_mesh(str(model_path)) # Compute normal colors mesh.compute_vertex_normals() state['normal_vertex_colors'] = (np.asarray(mesh.vertex_normals) + 1) / 2. if 'mesh' not in state['geometries']: state['geometries']['mesh'] = mesh else: state['geometries']['mesh'].vertices = mesh.vertices state['geometries']['mesh'].vertex_colors = mesh.vertex_colors state['geometries'][ 'mesh'].vertex_normals = mesh.vertex_normals state['geometries']['mesh'].triangles = mesh.triangles else: raise NotImplementedError() # Set normal colors to the mesh state['geometries']['mesh'].vertex_colors = o3d.Vector3dVector( state['normal_vertex_colors']) # Move Camera angle_y = np.clip(state['angle_y'], -90, 90) radius = np.clip(state['radius'], 0, state['radius']) pascal_az = (state['angle_z'] + 90) % 360 pascal_el = 90 - angle_y intrinsic = intrinsic_matrix(state['focal'], cx=img_w / 2, cy=img_h / 2) if args.verbose: print(f'Azimuth:{pascal_az} Elevation:{angle_y} Radius:{radius}') extrinsic = pascal_vpoint_to_extrinsics(az_deg=pascal_az, el_deg=pascal_el, radius=radius) if not vis.get_render_option() or not vis.get_view_control(): vis.update_geometry() # we don't have anything, return return align_view(vis, focal=state['focal'], extrinsic=extrinsic) vis.get_render_option().mesh_color_option = o3d.MeshColorOption.Color vis.get_render_option().light_on = False vis.get_render_option().background_color = (0, 0, 0) # Capture normal 2.5D sketch src_normal = np.asarray( vis.capture_screen_float_buffer(do_render=True)) src_normal = (src_normal * 255).astype(np.uint8) object_mask = np.all(src_normal == 0, axis=-1) if args.LAB: src_normal = cv2.cvtColor(src_normal, cv2.COLOR_RGB2LAB) else: raise ValueError('Released model was trained in LAB space.') # Project model kpoints in 2D kpoints_2d_step_dict = {} for k_name, k_val in state['kpoints_3d'].items(): point_3d = np.asarray([k_val]) kpoints_2d_step = project_points(point_3d, intrinsic, extrinsic) kpoints_2d_step /= (img_w, img_h) kpoints_2d_step = np.clip(kpoints_2d_step, -1, 1) kpoints_2d_step_dict[k_name] = kpoints_2d_step.squeeze(0) meta = { 'kpoints_2d': kpoints_2d_step_dict, 'vpoint': [pascal_az, pascal_el], 'cad_idx': state['cad_idx'] } dst_pl_info = get_planes(np.zeros((img_h, img_w, 3)), meta=meta, pascal_class=args.pascal_class, vis_oracle=state['vis_oracle']) _, dst_kpoints_planes, dst_visibilities = dst_pl_info texture_src = state['texture_src'] src_planes = np.asarray( [to_image(i, from_LAB=args.LAB) for i in texture_src['planes']]) src_kpoints_planes = texture_src['src_kpoints_planes'] src_visibilities = texture_src['src_vs'] planes_warped, planes_unwarped = warp_unwarp_planes( src_planes=src_planes, src_planes_kpoints=src_kpoints_planes, dst_planes_kpoints=dst_kpoints_planes, src_visibilities=src_visibilities, dst_visibilities=dst_visibilities, pascal_class=args.pascal_class) planes_warped = TextureDatasetWithNormal.planes_to_torch( planes_warped, to_LAB=args.LAB) planes_warped = planes_warped.reshape( 1, planes_warped.shape[0] * planes_warped.shape[1], planes_warped.shape[2], planes_warped.shape[3]) src_sketch_input = Normalize(mean=[0.5] * 3, std=[0.5] * 3)(ToTensor()( (Image.fromarray(src_normal)))) src_central = texture_src['src_central'] gen_in_src = torch.cat([ src_sketch_input.unsqueeze(0), src_central.unsqueeze(0), planes_warped ], dim=1).to(args.device) net_image = to_image(state['net'](gen_in_src)[0], from_LAB=args.LAB) # Use the normal image to mask artifacts net_image[object_mask] = 255 out_image = np.concatenate([ to_image(src_sketch_input, from_LAB=args.LAB), to_image(src_central, from_LAB=args.LAB), net_image, to_image(texture_src['src_image'], from_LAB=args.LAB) ], axis=1) state['dump_image'] = out_image cv2.imshow('Output', out_image) cv2.waitKey(20) vis.update_geometry()
return False vis = glb.vis vis.create_window(width=intrinsic.width, height=intrinsic.height) vis.add_geometry(mesh) vis.register_animation_callback(callback) vis.run() vis.destroy_window() if __name__ == "__main__": open3d.set_verbosity_level(open3d.VerbosityLevel.Debug) # Read camera pose and mesh camera = open3d.read_pinhole_camera_trajectory(os.path.join(path, "scene/key.log")) mesh = open3d.read_triangle_mesh(os.path.join(path, "scene", "integrated.ply")) color_image_path = get_file_list( os.path.join(path, "image/"), extension = ".jpg") if USE_Z_BUFFERING: depth_image_path = [osp.join('/tmp', fn.replace('jpg', 'png')) for fn in color_image_path] # generate depth maps save_depth_maps(mesh, camera.intrinsic, np.asarray(camera.extrinsic), depth_image_path) else: depth_filenames = get_file_list( os.path.join(path, "depth/"), extension = ".png") depth_image_path = []
def main(): mesh = o3d.read_triangle_mesh("ground_truth_surface/all.ply") custom_draw_geometry_with_view_tracking(mesh)
if __name__ == '__main__': import argparse parser = argparse.ArgumentParser(description='reweighted ICP algorithm') parser.add_argument('--source', type=str, help='source point cloud or mesh in .ply format') parser.add_argument('--target', type=str, help='target point cloud or mesh in .ply format') args = parser.parse_args() source = o3d.read_point_cloud(args.source) try: mesh = o3d.read_triangle_mesh(args.target) if np.array(mesh.triangles).shape[0] == 0: assert False v = np.array(mesh.vertices) tri = np.array(mesh.triangles) v1 = v[tri[:, 0], :] v2 = v[tri[:, 1], :] v3 = v[tri[:, 2], :] normals = np.cross(v1 - v3, v2 - v3) normals = (normals.T / np.linalg.norm(normals, 2, axis=1)).T centers = (v1 + v2 + v3) / 3.0 target = o3d.PointCloud() target.points = o3d.Vector3dVector(centers) target.normals = o3d.Vector3dVector(normals) except:
def main(): mesh = o3d.read_triangle_mesh("pesticide_bar.ply") #########change here generate = True period = 20 custom_draw_geometry_with_view_tracking(mesh, generate, period)
oy = 0.0 x_rot = ox + np.cos(angle) * (x_arr - ox) - np.sin(angle) * (y_arr - oy) y_rot = oy + np.sin(angle) * (x_arr - ox) + np.cos(angle) * (y_arr - oy) return x_rot, y_rot if __name__ == '__main__': config = read_config() read_mesh_path = config['data_path'] + "Tanum 89_1/Tanum 89_1 merge" read_data_path = config['save_path'] + "Tanum_89_1/Tanum_89_1_merge" mesh = o3d.read_triangle_mesh(read_mesh_path + '.stl') mesh.compute_vertex_normals() mesh.purge() vertices = np.asarray(mesh.vertices) normals = np.asarray(mesh.vertex_normals) transform_data = np.load(read_data_path + '/arrays/transform_meta.npz') components = transform_data['components'] mean = transform_data['mean'] rotation = transform_data['rotation'] vertices = np.dot(vertices - mean, components.T) normals = np.dot(normals, components.T) vertices[:, 0], vertices[:, 1] = rotate(vertices[:, 0], vertices[:, 1],
def get_mesh(self, mesh_name): mesh_name = mesh_name.replace('.pt', '') mesh_rgb_path = f"{self._original_meshes_dir}/{mesh_name}/{mesh_name}_vh_clean_2.ply" return open3d.read_triangle_mesh(mesh_rgb_path)
def main(): mesh = o3d.read_triangle_mesh("pesticide_bar.ply") #mesh = o3d.read_triangle_mesh("example.ply") #o3d.draw_geometries([mesh]) custom_draw_geometry_with_view_tracking(mesh)