1、主要参考
(1)官方稳定地址
Point cloud — Open3D 0.16.0 documentation
2、相关功能
2.1凸包(Convex hull)
(1)函数
compute_vertex_normals
create_from_triangle_mesh
(2)功能说明
点云的凸包是包含所有点的最小凸集。Open3D包含compute_convex_hull方法,用于计算点云的凸包。该实现基于Qhull。
(3)测试代码
在下面的示例代码中,我们首先从网格中采样一个点云,并计算作为三角形网格返回的凸包。然后,我们将凸包可视化为一个红色的LineSet。
1)本次测试还是那只兔子,原始的3d显示如下
import open3d as o3d
import numpy as np
#网络下载,官方例子
# bunny = o3d.data.BunnyMesh()
# mesh = o3d.io.read_triangle_mesh(bunny.path)
#或者下载后本地读取
#https://github.com/isl-org/open3d_downloads/releases/download/20220201-data/BunnyMesh.ply
plypath = "D:/RGBD_CAMERA/python_3d_process/BunnyMesh/BunnyMesh.ply"
# mesh = o3d.io.read_point_cloud(plypath) # path为文件路径 #直接读取点云的方法
mesh = o3d.io.read_triangle_mesh(plypath) # path为文件路径
o3d.visualization.draw_geometries([mesh])
兔子的图,网络问题暂时上传不了
注意:读取时使用了read_triangle_mesh(三角网格)而不是read_point_cloud
2)方法一直接对兔子做凸包
import open3d as o3d
import numpy as np
#网络下载,官方例子
# bunny = o3d.data.BunnyMesh()
# mesh = o3d.io.read_triangle_mesh(bunny.path)
#或者下载后本地读取
#https://github.com/isl-org/open3d_downloads/releases/download/20220201-data/BunnyMesh.ply
plypath = "D:/RGBD_CAMERA/python_3d_process/BunnyMesh/BunnyMesh.ply"
# mesh = o3d.io.read_point_cloud(plypath) # path为文件路径 #直接读取点云的方法
mesh = o3d.io.read_triangle_mesh(plypath) # path为文件路径
# o3d.visualization.draw_geometries([mesh])
#(方法一)直接对兔子做凸包
hull, _ = mesh.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([mesh,hull_ls])
#(方法二)对兔子采样后做凸包
# 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])
兔子的图如下
3)方法二,对兔子进行下采样后做凸包
import open3d as o3d
import numpy as np
#网络下载,官方例子
# bunny = o3d.data.BunnyMesh()
# mesh = o3d.io.read_triangle_mesh(bunny.path)
#或者下载后本地读取
#https://github.com/isl-org/open3d_downloads/releases/download/20220201-data/BunnyMesh.ply
plypath = "D:/RGBD_CAMERA/python_3d_process/BunnyMesh/BunnyMesh.ply"
# mesh = o3d.io.read_point_cloud(plypath) # path为文件路径 #直接读取点云的方法
mesh = o3d.io.read_triangle_mesh(plypath) # path为文件路径
# o3d.visualization.draw_geometries([mesh])
#(方法一)直接对兔子做凸包
# hull, _ = mesh.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([mesh,hull_ls])
#(方法二)对兔子采样后做凸包
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])
兔子的图如下
(4)函数说明
sample_points_poisson_disk -- 泊松磁盘采样,下采样的一个方法
2.2 DBSCAN 分类集群(DBSCAN clustering)
(1)函数
cluster_dbscan(eps=0.02, min_points=10, print_progress=True)
(2)说明
给定一个点云,例如一个深度传感器,我们希望将局部点云数据集群分组在一起。为此,我们可以使用聚类算法。Open3D实现了DBSCAN [Ester1996],这是一种基于密度的聚类算法。该算法在cluster_dbscan中实现,需要两个参数:eps定义到集群中邻居的距离,min_points定义形成集群所需的最小点数。函数返回标签,其中标签-1表示噪声。
(3)测试代码
import open3d as o3d
import numpy as np
from matplotlib import pyplot as plt
# 初次使用下载模型
# ply_point_cloud = o3d.data.PLYPointCloud()
# pcd = o3d.io.read_point_cloud(ply_point_cloud.path)
# 或者直接使用本地
plypath = "D:/RGBD_CAMERA/python_3d_process/DemoCropPointCloud/fragment.ply"
pcd = o3d.io.read_point_cloud(plypath) # path为文件路径
with o3d.utility.VerbosityContextManager(
o3d.utility.VerbosityLevel.Debug) as cm:
labels = np.array(
pcd.cluster_dbscan(eps=0.02, min_points=10, print_progress=True))
max_label = labels.max()
print(f"point cloud has {max_label + 1} clusters")
colors = plt.get_cmap("tab20")(labels / (max_label if max_label > 0 else 1))
colors[labels < 0] = 0
pcd.colors = o3d.utility.Vector3dVector(colors[:, :3])
o3d.visualization.draw_geometries([pcd],
zoom=0.455,
front=[-0.4999, -0.1659, -0.8499],
lookat=[2.1813, 2.0619, 2.0999],
up=[0.1204, -0.9852, 0.1215])
(4)测试结果
(稍微大一点的截图就没法上传,只能上小图)
该算法预先计算了所有点在半径内的所有邻点。如果所选eps太大,这可能需要大量内存。
(5)自己的例子,未剔除点云的处理结果
import open3d as o3d
import numpy as np
from matplotlib import pyplot as plt
# 初次使用下载模型
# ply_point_cloud = o3d.data.PLYPointCloud()
# pcd = o3d.io.read_point_cloud(ply_point_cloud.path)
# 或者直接使用本地
# plypath = "D:/RGBD_CAMERA/python_3d_process/DemoCropPointCloud/fragment.ply"
plypath = "D:/RGBD_CAMERA/python_3d_process/1_hezi.pcd"
pcd = o3d.io.read_point_cloud(plypath) # path为文件路径
pcd = pcd.remove_non_finite_points(True, False)#剔除无效值
with o3d.utility.VerbosityContextManager(
o3d.utility.VerbosityLevel.Debug) as cm:
labels = np.array(
# pcd.cluster_dbscan(eps=0.02, min_points=10, print_progress=True))
pcd.cluster_dbscan(eps=10, min_points=200, print_progress=True))
max_label = labels.max()
print(f"point cloud has {max_label + 1} clusters")
colors = plt.get_cmap("tab20")(labels / (max_label if max_label > 0 else 1))
colors[labels < 0] = 0
pcd.colors = o3d.utility.Vector3dVector(colors[:, :3])
o3d.visualization.draw_geometries([pcd],
zoom=0.455,
front=[-0.4999, -0.1659, -0.8499],
lookat=[2.1813, 2.0619, 2.0999],
up=[0.1204, -0.9852, 0.1215])