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])