# Voxel Grid¶

## voxel_grid_carving.py¶

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 # ---------------------------------------------------------------------------- # - Open3D: www.open3d.org - # ---------------------------------------------------------------------------- # The MIT License (MIT) # # Copyright (c) 2018-2021 www.open3d.org # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # ---------------------------------------------------------------------------- import open3d as o3d import numpy as np def xyz_spherical(xyz): x = xyz[0] y = xyz[1] z = xyz[2] r = np.sqrt(x * x + y * y + z * z) r_x = np.arccos(y / r) r_y = np.arctan2(z, x) return [r, r_x, r_y] def get_rotation_matrix(r_x, r_y): rot_x = np.asarray([[1, 0, 0], [0, np.cos(r_x), -np.sin(r_x)], [0, np.sin(r_x), np.cos(r_x)]]) rot_y = np.asarray([[np.cos(r_y), 0, np.sin(r_y)], [0, 1, 0], [-np.sin(r_y), 0, np.cos(r_y)]]) return rot_y.dot(rot_x) def get_extrinsic(xyz): rvec = xyz_spherical(xyz) r = get_rotation_matrix(rvec[1], rvec[2]) t = np.asarray([0, 0, 2]).transpose() trans = np.eye(4) trans[:3, :3] = r trans[:3, 3] = t return trans def preprocess(model): min_bound = model.get_min_bound() max_bound = model.get_max_bound() center = min_bound + (max_bound - min_bound) / 2.0 scale = np.linalg.norm(max_bound - min_bound) / 2.0 vertices = np.asarray(model.vertices) vertices -= center model.vertices = o3d.utility.Vector3dVector(vertices / scale) return model def voxel_carving(mesh, cubic_size, voxel_resolution, w=300, h=300): mesh.compute_vertex_normals() camera_sphere = o3d.geometry.TriangleMesh.create_sphere(radius=1.0, resolution=10) # Setup dense voxel grid. voxel_carving = o3d.geometry.VoxelGrid.create_dense( width=cubic_size, height=cubic_size, depth=cubic_size, voxel_size=cubic_size / voxel_resolution, origin=[-cubic_size / 2.0, -cubic_size / 2.0, -cubic_size / 2.0], color=[1.0, 0.7, 0.0]) # Rescale geometry. camera_sphere = preprocess(camera_sphere) mesh = preprocess(mesh) # Setup visualizer to render depthmaps. vis = o3d.visualization.Visualizer() vis.create_window(width=w, height=h, visible=False) vis.add_geometry(mesh) vis.get_render_option().mesh_show_back_face = True ctr = vis.get_view_control() param = ctr.convert_to_pinhole_camera_parameters() # Carve voxel grid. centers_pts = np.zeros((len(camera_sphere.vertices), 3)) for cid, xyz in enumerate(camera_sphere.vertices): # Get new camera pose. trans = get_extrinsic(xyz) param.extrinsic = trans c = np.linalg.inv(trans).dot(np.asarray([0, 0, 0, 1]).transpose()) centers_pts[cid, :] = c[:3] ctr.convert_from_pinhole_camera_parameters(param) # Capture depth image and make a point cloud. vis.poll_events() vis.update_renderer() depth = vis.capture_depth_float_buffer(False) # Depth map carving method. voxel_carving.carve_depth_map(o3d.geometry.Image(depth), param) print("Carve view %03d/%03d" % (cid + 1, len(camera_sphere.vertices))) vis.destroy_window() return voxel_carving if __name__ == "__main__": armadillo_data = o3d.data.ArmadilloMesh() mesh = o3d.io.read_triangle_mesh(armadillo_data.path) cubic_size = 2.0 voxel_resolution = 128.0 carved_voxels = voxel_carving(mesh, cubic_size, voxel_resolution) print("Carved voxels ...") print(carved_voxels) o3d.visualization.draw([carved_voxels]) 

## voxel_grid_from_point_cloud.py¶

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 # ---------------------------------------------------------------------------- # - Open3D: www.open3d.org - # ---------------------------------------------------------------------------- # The MIT License (MIT) # # Copyright (c) 2018-2021 www.open3d.org # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # ---------------------------------------------------------------------------- import open3d as o3d import numpy as np if __name__ == "__main__": N = 2000 armadillo_data = o3d.data.ArmadilloMesh() pcd = o3d.io.read_triangle_mesh( armadillo_data.path).sample_points_poisson_disk(N) # Fit to unit cube. pcd.scale(1 / np.max(pcd.get_max_bound() - pcd.get_min_bound()), center=pcd.get_center()) pcd.colors = o3d.utility.Vector3dVector(np.random.uniform(0, 1, size=(N, 3))) print('Displaying input point cloud ...') o3d.visualization.draw([pcd]) print('Displaying voxel grid ...') voxel_grid = o3d.geometry.VoxelGrid.create_from_point_cloud(pcd, voxel_size=0.05) o3d.visualization.draw([voxel_grid]) 

## voxel_grid_from_triangle_mesh.py¶

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 # ---------------------------------------------------------------------------- # - Open3D: www.open3d.org - # ---------------------------------------------------------------------------- # The MIT License (MIT) # # Copyright (c) 2018-2021 www.open3d.org # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # ---------------------------------------------------------------------------- import open3d as o3d import numpy as np if __name__ == "__main__": bunny = o3d.data.BunnyMesh() mesh = o3d.io.read_triangle_mesh(bunny.path) mesh.compute_vertex_normals() # Fit to unit cube. mesh.scale(1 / np.max(mesh.get_max_bound() - mesh.get_min_bound()), center=mesh.get_center()) print('Displaying input mesh ...') o3d.visualization.draw([mesh]) voxel_grid = o3d.geometry.VoxelGrid.create_from_triangle_mesh( mesh, voxel_size=0.05) print('Displaying voxel grid ...') o3d.visualization.draw([voxel_grid])