Point Cloud#
point_cloud_bounding_box.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9
10if __name__ == "__main__":
11 sample_ply_data = o3d.data.PLYPointCloud()
12 pcd = o3d.io.read_point_cloud(sample_ply_data.path)
13 # Flip it, otherwise the pointcloud will be upside down.
14 pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
15 print(pcd)
16 axis_aligned_bounding_box = pcd.get_axis_aligned_bounding_box()
17 axis_aligned_bounding_box.color = (1, 0, 0)
18 oriented_bounding_box = pcd.get_oriented_bounding_box()
19 oriented_bounding_box.color = (0, 1, 0)
20 print(
21 "Displaying axis_aligned_bounding_box in red and oriented bounding box in green ..."
22 )
23 o3d.visualization.draw(
24 [pcd, axis_aligned_bounding_box, oriented_bounding_box])
point_cloud_convex_hull.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9
10if __name__ == "__main__":
11
12 print("Displaying pointcloud with convex hull ...")
13 bunny = o3d.data.BunnyMesh()
14 mesh = o3d.io.read_triangle_mesh(bunny.path)
15 mesh.compute_vertex_normals()
16
17 pcl = mesh.sample_points_poisson_disk(number_of_points=10000)
18 hull, _ = pcl.compute_convex_hull()
19 hull_ls = o3d.geometry.LineSet.create_from_triangle_mesh(hull)
20 hull_ls.paint_uniform_color((1, 0, 0))
21 o3d.visualization.draw([pcl, hull_ls])
point_cloud_crop.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9
10if __name__ == "__main__":
11 print("Load a ply point cloud, crop it, and render it")
12 sample_ply_data = o3d.data.DemoCropPointCloud()
13 pcd = o3d.io.read_point_cloud(sample_ply_data.point_cloud_path)
14 vol = o3d.visualization.read_selection_polygon_volume(
15 sample_ply_data.cropped_json_path)
16 chair = vol.crop_point_cloud(pcd)
17 # Flip the pointclouds, otherwise they will be upside down.
18 pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
19 chair.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
20
21 print("Displaying original pointcloud ...")
22 o3d.visualization.draw([pcd])
23 print("Displaying cropped pointcloud")
24 o3d.visualization.draw([chair])
point_cloud_dbscan_clustering.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9import numpy as np
10import matplotlib.pyplot as plt
11
12if __name__ == "__main__":
13 sample_ply_data = o3d.data.PLYPointCloud()
14 pcd = o3d.io.read_point_cloud(sample_ply_data.path)
15 # Flip it, otherwise the pointcloud will be upside down.
16 pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
17
18 with o3d.utility.VerbosityContextManager(
19 o3d.utility.VerbosityLevel.Debug) as cm:
20 labels = np.array(
21 pcd.cluster_dbscan(eps=0.02, min_points=10, print_progress=True))
22
23 max_label = labels.max()
24 print(f"point cloud has {max_label + 1} clusters")
25 colors = plt.get_cmap("tab20")(labels / (max_label if max_label > 0 else 1))
26 colors[labels < 0] = 0
27 pcd.colors = o3d.utility.Vector3dVector(colors[:, :3])
28 o3d.visualization.draw([pcd])
point_cloud_distance.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9import numpy as np
10
11if __name__ == "__main__":
12 sample_ply_data = o3d.data.DemoCropPointCloud()
13 pcd = o3d.io.read_point_cloud(sample_ply_data.point_cloud_path)
14 vol = o3d.visualization.read_selection_polygon_volume(
15 sample_ply_data.cropped_json_path)
16 chair = vol.crop_point_cloud(pcd)
17
18 chair.paint_uniform_color([0, 0, 1])
19 pcd.paint_uniform_color([1, 0, 0])
20 print("Displaying the two point clouds used for calculating distance ...")
21 o3d.visualization.draw([pcd, chair])
22
23 dists = pcd.compute_point_cloud_distance(chair)
24 dists = np.asarray(dists)
25 print("Printing average distance between the two point clouds ...")
26 print(dists)
point_cloud_farthest_point_sampling.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9
10if __name__ == "__main__":
11 # Load bunny data.
12 bunny = o3d.data.BunnyMesh()
13 pcd = o3d.io.read_point_cloud(bunny.path)
14 pcd.paint_uniform_color([0.5, 0.5, 0.5])
15
16 # Get 1000 samples from original point cloud and paint to green.
17 pcd_down = pcd.farthest_point_down_sample(1000)
18 pcd_down.paint_uniform_color([0, 1, 0])
19 o3d.visualization.draw_geometries([pcd, pcd_down])
point_cloud_iss_keypoint_detector.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9import time
10
11if __name__ == "__main__":
12 # Compute ISS Keypoints on armadillo pointcloud.
13 armadillo_data = o3d.data.ArmadilloMesh()
14 mesh = o3d.io.read_triangle_mesh(armadillo_data.path)
15 pcd = o3d.geometry.PointCloud()
16 pcd.points = mesh.vertices
17
18 tic = time.time()
19 keypoints = o3d.geometry.keypoint.compute_iss_keypoints(pcd)
20 toc = 1000 * (time.time() - tic)
21 print("ISS Computation took {:.0f} [ms]".format(toc))
22
23 mesh.compute_vertex_normals()
24 mesh.paint_uniform_color([0.5, 0.5, 0.5])
25 keypoints.paint_uniform_color([1.0, 0.0, 0.0])
26 o3d.visualization.draw([keypoints, mesh], point_size=5)
point_cloud_normal_estimation.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9import numpy as np
10
11if __name__ == "__main__":
12 bunny = o3d.data.BunnyMesh()
13 gt_mesh = o3d.io.read_triangle_mesh(bunny.path)
14 gt_mesh.compute_vertex_normals()
15
16 pcd = gt_mesh.sample_points_poisson_disk(5000)
17 # Invalidate existing normals.
18 pcd.normals = o3d.utility.Vector3dVector(np.zeros((1, 3)))
19
20 print("Displaying input pointcloud ...")
21 o3d.visualization.draw_geometries([pcd], point_show_normal=True)
22
23 pcd.estimate_normals()
24 print("Displaying pointcloud with normals ...")
25 o3d.visualization.draw_geometries([pcd], point_show_normal=True)
26
27 print("Printing the normal vectors ...")
28 print(np.asarray(pcd.normals))
point_cloud_outlier_removal_radius.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9import numpy as np
10
11
12def display_inlier_outlier(cloud, ind):
13 inlier_cloud = cloud.select_by_index(ind)
14 outlier_cloud = cloud.select_by_index(ind, invert=True)
15
16 print("Showing outliers (red) and inliers (gray): ")
17 outlier_cloud.paint_uniform_color([1, 0, 0])
18 inlier_cloud.paint_uniform_color([0.8, 0.8, 0.8])
19 o3d.visualization.draw([inlier_cloud, outlier_cloud])
20
21
22if __name__ == "__main__":
23 ptcloud_data = o3d.data.PLYPointCloud()
24
25 print("Load a ply point cloud, print it, and render it")
26 pcd = o3d.io.read_point_cloud(ptcloud_data.path)
27 R = pcd.get_rotation_matrix_from_xyz((np.pi, 0, 0))
28 pcd.rotate(R, center=(0, 0, 0))
29 o3d.visualization.draw([pcd])
30
31 print("Downsample the point cloud with a voxel of 0.02")
32 voxel_down_pcd = pcd.voxel_down_sample(voxel_size=0.02)
33 o3d.visualization.draw([voxel_down_pcd])
34
35 print("Radius oulier removal")
36 cl, ind = voxel_down_pcd.remove_radius_outlier(nb_points=16, radius=0.05)
37 display_inlier_outlier(voxel_down_pcd, ind)
point_cloud_outlier_removal_statistical.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9import numpy as np
10
11
12def display_inlier_outlier(cloud, ind):
13 inlier_cloud = cloud.select_by_index(ind)
14 outlier_cloud = cloud.select_by_index(ind, invert=True)
15
16 print("Showing outliers (red) and inliers (gray): ")
17 outlier_cloud.paint_uniform_color([1, 0, 0])
18 inlier_cloud.paint_uniform_color([0.8, 0.8, 0.8])
19 o3d.visualization.draw([inlier_cloud, outlier_cloud])
20
21
22if __name__ == "__main__":
23 ptcloud_data = o3d.data.PLYPointCloud()
24
25 print("Load a ply point cloud, print it, and render it")
26 pcd = o3d.io.read_point_cloud(ptcloud_data.path)
27 R = pcd.get_rotation_matrix_from_xyz((np.pi, 0, 0))
28 pcd.rotate(R, center=(0, 0, 0))
29 o3d.visualization.draw([pcd])
30
31 print("Downsample the point cloud with a voxel of 0.02")
32 voxel_down_pcd = pcd.voxel_down_sample(voxel_size=0.02)
33 o3d.visualization.draw([voxel_down_pcd])
34
35 print("Statistical oulier removal")
36 cl, ind = voxel_down_pcd.remove_statistical_outlier(nb_neighbors=20,
37 std_ratio=2.0)
38 display_inlier_outlier(voxel_down_pcd, ind)
point_cloud_paint.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9
10if __name__ == "__main__":
11 print("Load a ply point cloud, print it, and render it")
12 sample_ply_data = o3d.data.PLYPointCloud()
13 pcd = o3d.io.read_point_cloud(sample_ply_data.path)
14 # Flip it, otherwise the pointcloud will be upside down.
15 pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
16 print(pcd)
17 o3d.visualization.draw([pcd])
18 print("Paint pointcloud")
19 pcd.paint_uniform_color([1, 0.706, 0])
20 o3d.visualization.draw([pcd])
point_cloud_plane_segmentation.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9
10if __name__ == "__main__":
11
12 sample_pcd_data = o3d.data.PCDPointCloud()
13 pcd = o3d.io.read_point_cloud(sample_pcd_data.path)
14 # Flip it, otherwise the pointcloud will be upside down.
15 pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
16 plane_model, inliers = pcd.segment_plane(distance_threshold=0.01,
17 ransac_n=3,
18 num_iterations=1000)
19 [a, b, c, d] = plane_model
20 print(f"Plane equation: {a:.2f}x + {b:.2f}y + {c:.2f}z + {d:.2f} = 0")
21 print("Displaying pointcloud with planar points in red ...")
22 inlier_cloud = pcd.select_by_index(inliers)
23 inlier_cloud.paint_uniform_color([1.0, 0, 0])
24 outlier_cloud = pcd.select_by_index(inliers, invert=True)
25 o3d.visualization.draw([inlier_cloud, outlier_cloud])
point_cloud_to_depth.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9import numpy as np
10import matplotlib.pyplot as plt
11
12if __name__ == '__main__':
13 tum_data = o3d.data.SampleTUMRGBDImage()
14 depth = o3d.t.io.read_image(tum_data.depth_path)
15 intrinsic = o3d.core.Tensor([[535.4, 0, 320.1], [0, 539.2, 247.6],
16 [0, 0, 1]])
17
18 pcd = o3d.t.geometry.PointCloud.create_from_depth_image(depth,
19 intrinsic,
20 depth_scale=5000.0,
21 depth_max=10.0)
22 o3d.visualization.draw([pcd])
23 depth_reproj = pcd.project_to_depth_image(640,
24 480,
25 intrinsic,
26 depth_scale=5000.0,
27 depth_max=10.0)
28
29 fig, axs = plt.subplots(1, 2)
30 axs[0].imshow(np.asarray(depth.to_legacy()))
31 axs[1].imshow(np.asarray(depth_reproj.to_legacy()))
32 plt.show()
point_cloud_to_rgbd.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9import numpy as np
10import matplotlib.pyplot as plt
11
12if __name__ == '__main__':
13 device = o3d.core.Device('CPU:0')
14 tum_data = o3d.data.SampleTUMRGBDImage()
15 depth = o3d.t.io.read_image(tum_data.depth_path).to(device)
16 color = o3d.t.io.read_image(tum_data.color_path).to(device)
17
18 intrinsic = o3d.core.Tensor([[535.4, 0, 320.1], [0, 539.2, 247.6],
19 [0, 0, 1]])
20 rgbd = o3d.t.geometry.RGBDImage(color, depth)
21
22 pcd = o3d.t.geometry.PointCloud.create_from_rgbd_image(rgbd,
23 intrinsic,
24 depth_scale=5000.0,
25 depth_max=10.0)
26 o3d.visualization.draw([pcd])
27 rgbd_reproj = pcd.project_to_rgbd_image(640,
28 480,
29 intrinsic,
30 depth_scale=5000.0,
31 depth_max=10.0)
32
33 fig, axs = plt.subplots(1, 2)
34 axs[0].imshow(np.asarray(rgbd_reproj.color.to_legacy()))
35 axs[1].imshow(np.asarray(rgbd_reproj.depth.to_legacy()))
36 plt.show()
point_cloud_transformation.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9import numpy as np
10import copy
11
12
13def translate():
14 armadillo_data = o3d.data.ArmadilloMesh()
15 pcd = o3d.io.read_triangle_mesh(
16 armadillo_data.path).sample_points_poisson_disk(5000)
17 pcd_tx = copy.deepcopy(pcd).translate((150, 0, 0))
18 pcd_ty = copy.deepcopy(pcd).translate((0, 200, 0))
19 print('Displaying original and translated geometries ...')
20 o3d.visualization.draw([{
21 "name": "Original Geometry",
22 "geometry": pcd
23 }, {
24 "name": "Translated (in X) Geometry",
25 "geometry": pcd_tx
26 }, {
27 "name": "Translated (in Y) Geometry",
28 "geometry": pcd_ty
29 }],
30 show_ui=True)
31
32
33def rotate():
34 armadillo_data = o3d.data.ArmadilloMesh()
35 pcd = o3d.io.read_triangle_mesh(
36 armadillo_data.path).sample_points_poisson_disk(5000)
37 pcd_r = copy.deepcopy(pcd).translate((200, 0, 0))
38 R = pcd.get_rotation_matrix_from_xyz((np.pi / 2, 0, np.pi / 4))
39 pcd_r.rotate(R)
40 print('Displaying original and rotated geometries ...')
41 o3d.visualization.draw([{
42 "name": "Original Geometry",
43 "geometry": pcd
44 }, {
45 "name": "Rotated Geometry",
46 "geometry": pcd_r
47 }],
48 show_ui=True)
49
50
51def scale():
52 armadillo_data = o3d.data.ArmadilloMesh()
53 pcd = o3d.io.read_triangle_mesh(
54 armadillo_data.path).sample_points_poisson_disk(5000)
55 pcd_s = copy.deepcopy(pcd).translate((200, 0, 0))
56 pcd_s.scale(0.5, center=pcd_s.get_center())
57 print('Displaying original and scaled geometries ...')
58 o3d.visualization.draw([{
59 "name": "Original Geometry",
60 "geometry": pcd
61 }, {
62 "name": "Scaled Geometry",
63 "geometry": pcd_s
64 }],
65 show_ui=True)
66
67
68def transform():
69 armadillo_data = o3d.data.ArmadilloMesh()
70 pcd = o3d.io.read_triangle_mesh(
71 armadillo_data.path).sample_points_poisson_disk(5000)
72 T = np.eye(4)
73 T[:3, :3] = pcd.get_rotation_matrix_from_xyz((0, np.pi / 3, np.pi / 2))
74 T[0, 3] = 150
75 T[1, 3] = 200
76 print(T)
77 pcd_t = copy.deepcopy(pcd).transform(T)
78 print('Displaying original and transformed geometries ...')
79 o3d.visualization.draw([{
80 "name": "Original Geometry",
81 "geometry": pcd
82 }, {
83 "name": "Transformed Geometry",
84 "geometry": pcd_t
85 }],
86 show_ui=True)
87
88
89if __name__ == "__main__":
90
91 translate()
92 rotate()
93 scale()
94 transform()
point_cloud_voxel_downsampling.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9
10if __name__ == "__main__":
11 print("Load a ply point cloud, print it, and render it")
12 sample_ply_data = o3d.data.PLYPointCloud()
13 pcd = o3d.io.read_point_cloud(sample_ply_data.path)
14 # Flip it, otherwise the pointcloud will be upside down.
15 pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
16 print(pcd)
17 o3d.visualization.draw([pcd])
18 print("Downsample the point cloud with a voxel of 0.05")
19 downpcd = pcd.voxel_down_sample(voxel_size=0.05)
20 o3d.visualization.draw([downpcd])
point_cloud_with_numpy.py#
1# ----------------------------------------------------------------------------
2# - Open3D: www.open3d.org -
3# ----------------------------------------------------------------------------
4# Copyright (c) 2018-2024 www.open3d.org
5# SPDX-License-Identifier: MIT
6# ----------------------------------------------------------------------------
7
8import open3d as o3d
9import numpy as np
10
11if __name__ == "__main__":
12 # Generate some n x 3 matrix using a variant of sync function.
13 x = np.linspace(-3, 3, 201)
14 mesh_x, mesh_y = np.meshgrid(x, x)
15 z = np.sinc((np.power(mesh_x, 2) + np.power(mesh_y, 2)))
16 z_norm = (z - z.min()) / (z.max() - z.min())
17 xyz = np.zeros((np.size(mesh_x), 3))
18 xyz[:, 0] = np.reshape(mesh_x, -1)
19 xyz[:, 1] = np.reshape(mesh_y, -1)
20 xyz[:, 2] = np.reshape(z_norm, -1)
21 print("Printing numpy array used to make Open3D pointcloud ...")
22 print(xyz)
23
24 # Pass xyz to Open3D.o3d.geometry.PointCloud and visualize.
25 pcd = o3d.geometry.PointCloud()
26 pcd.points = o3d.utility.Vector3dVector(xyz)
27 # Add color and estimate normals for better visualization.
28 pcd.paint_uniform_color([0.5, 0.5, 0.5])
29 pcd.estimate_normals()
30 pcd.orient_normals_consistent_tangent_plane(1)
31 print("Displaying Open3D pointcloud made using numpy array ...")
32 o3d.visualization.draw([pcd])
33
34 # Convert Open3D.o3d.geometry.PointCloud to numpy array.
35 xyz_converted = np.asarray(pcd.points)
36 print("Printing numpy array made using Open3D pointcloud ...")
37 print(xyz_converted)