一、Visualize point cloud
import open3d as o3d
import numpy as np
print("Load a ply point cloud, print it, and render it")
ply_point_cloud = o3d.data.PLYPointCloud()
pcd = o3d.data.PLYPointCloud()
print(pcd)
print(np.asarray(pcd.points))
o3d.visualization.draw_geometries([pcd],
zoom=0.3412,
front=[0.4257, -0.2125, -0.8795],
lookat=[2.6172, 2.0475, 1.532],
up=[-0.0694, -0.9768, 0.2024])
o3d.io.read_point_cloud(ply_point_cloud.path)——通过对象本地地址io读取,转换为open3d.cuda.pybind.geometry.PointCloud对象
np.asarray(pcd.points)——以列表形式展示点云的固定格式,每个点有三个坐标元素
[[0.65234375 0.84686458 2.37890625]
[0.65234375 0.83984375 2.38430572]
[0.66737998 0.83984375 2.37890625]
...
[2.00839925 2.39453125 1.88671875]
[2.00390625 2.39488506 1.88671875]
[2.00390625 2.39453125 1.88793314]].shape:196133*3
o3d.visualization.draw_geometries([pcd])——打印pcd(open3d.cuda.pybind.geometry.PointCloud对象),后面的是定位不加也可以打印
二、Voxel downsampling
print("Downsample the point cloud with a voxel of 0.05")
downpcd = pcd.voxel_down_sample(voxel_size=0.05)
o3d.visualization.draw_geometries([downpcd],
zoom=0.3412,
front=[0.4257, -0.2125, -0.8795],
lookat=[2.6172, 2.0475, 1.532],
up=[-0.0694, -0.9768, 0.2024])
pcd.voxel_down_sample(voxel_size=0.1)——下采样,数字越大单个样本越大,得到点越少
三、Vertex normal estimation
print("Recompute the normal of the downsampled point cloud")
downpcd.estimate_normals(
search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))
o3d.visualization.draw_geometries([downpcd],
zoom=0.3412,
front=[0.4257, -0.2125, -0.8795],
lookat=[2.6172, 2.0475, 1.532],
up=[-0.0694, -0.9768, 0.2024],
point_show_normal=True)
五、Crop point cloud
print("Load a polygon volume and use it to crop the original point cloud")
demo_crop_data = o3d.data.DemoCropPointCloud()
pcd = o3d.io.read_point_cloud(demo_crop_data.point_cloud_path)
vol = o3d.visualization.read_selection_polygon_volume(demo_crop_data.cropped_json_path)
chair = vol.crop_point_cloud(pcd)
o3d.visualization.draw_geometries([chair],
zoom=0.7,
front=[0.5439, -0.2333, -0.8060],
lookat=[2.4615, 2.1331, 1.338],
up=[-0.1781, -0.9708, 0.1608])
demo_crop_data.point_cloud_path——点云路径
o3d.visualization.read_selection_polygon_volume(demo_crop_data.cropped_json_path)——读取切割区域
vol.crop_point_cloud(pcd)——切割区域.crop_point_cloud(原文件)
六、Paint point cloud
print("Paint chair")
chair.paint_uniform_color([1, 0.706, 0])
o3d.visualization.draw_geometries([chair],
zoom=0.7,
front=[0.5439, -0.2333, -0.8060],
lookat=[2.4615, 2.1331, 1.338],
up=[-0.1781, -0.9708, 0.1608])
paint_uniform_color
——统一涂色, The color is in RGB space, [0, 1] range.
七、Point cloud distance
# Load data
demo_crop_data = o3d.data.DemoCropPointCloud()
pcd = o3d.io.read_point_cloud(demo_crop_data.point_cloud_path)
vol = o3d.visualization.read_selection_polygon_volume(demo_crop_data.cropped_json_path)
chair = vol.crop_point_cloud(pcd)
dists = pcd.compute_point_cloud_distance(chair)
dists = np.asarray(dists)
ind = np.where(dists > 0.01)[0]
pcd_without_chair = pcd.select_by_index(ind)
o3d.visualization.draw_geometries([pcd_without_chair],
zoom=0.3412,
front=[0.4257, -0.2125, -0.8795],
lookat=[2.6172, 2.0475, 1.532],
up=[-0.0694, -0.9768, 0.2024])
dists = pcd.compute_point_cloud_distance(chair) # 原点云.compute_point_cloud_distance(目标点云)
dists = np.asarray(dists) ## 通常格式:得出距离的一维数组
ind = np.where(dists>0.01)[0] # 得出满足条件的点序列号
pcd.select_by_index(ind)——按ind中的序列号取pcd的点
去除噪音范例:https://zhuanlan.zhihu.com/p/462325566#:~:text=Open3D中的,compute_point_cloud_distance 函数计算从源点云中每个点到目标点云中最近邻点的距离。
八、Bounding volumes
aabb = chair.get_axis_aligned_bounding_box() # 获取轴对齐边框
aabb.color = (1, 0, 0) # 红色框
obb = chair.get_oriented_bounding_box() # 获取定向包围框
obb.color = (0, 1, 0) # 绿色框
o3d.visualization.draw_geometries([chair, aabb, obb],
zoom=0.7,
front=[0.5439, -0.2333, -0.8060],
lookat=[2.4615, 2.1331, 1.338],
up=[-0.1781, -0.9708, 0.1608])
九、Convex hull
bunny = o3d.data.BunnyMesh()
mesh = o3d.io.read_triangle_mesh(bunny.path)
mesh.compute_vertex_normals()
pcl = mesh.sample_points_poisson_disk(number_of_points=2000)
hull, _ = pcl.compute_convex_hull()
hull_ls = o3d.geometry.LineSet.create_from_triangle_mesh(hull)
hull_ls.paint_uniform_color((1, 0, 0))
o3d.visualization.draw_geometries([pcl, hull_ls])
十一、Plane segmentation最大支撑的平面分割
pcd_point_cloud = o3d.data.PCDPointCloud()
pcd = o3d.io.read_point_cloud(pcd_point_cloud.path)
plane_model, inliers = pcd.segment_plane(distance_threshold=0.01,
ransac_n=3,
num_iterations=1000)
# distance_threshold:一个点到估计平面的最大距离可以被认为是内平面
# ransac_n:随机抽样来估计一个平面的点数
# num_iterations:随机平面抽样和验证的频率
[a, b, c, d] = plane_model
print(f"Plane equation: {a:.2f}x + {b:.2f}y + {c:.2f}z + {d:.2f} = 0")
inlier_cloud = pcd.select_by_index(inliers) # 按照inliers序列选择点
inlier_cloud.paint_uniform_color([1.0, 0, 0]) # 内平面涂色
outlier_cloud = pcd.select_by_index(inliers, invert=True) # 利用反选平面外部分
o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud],
zoom=0.8,
front=[-0.4999, -0.1659, -0.8499],
lookat=[2.1813, 2.0619, 2.0999],
up=[0.1204, -0.9852, 0.1215])