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