点云离群点去除
在使用扫描设备采集数据时,所得点云往往含有需要去除的噪声和伪影(artifacts)。本教程介绍 Open3D 的离群点去除(outlier removal)功能。
准备输入数据
Section titled “准备输入数据”加载一个点云,并使用 voxel_downsample 进行降采样。
print("Load a ply point cloud, print it, and render it")sample_pcd_data = o3d.data.PCDPointCloud()pcd = o3d.io.read_point_cloud(sample_pcd_data.path)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])
print("Downsample the point cloud with a voxel of 0.02")voxel_down_pcd = pcd.voxel_down_sample(voxel_size=0.02)o3d.visualization.draw_geometries([voxel_down_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])

输出:
Load a ply point cloud, print it, and render itDownsample the point cloud with a voxel of 0.02此外,也可以使用 uniform_down_sample,通过每隔 n 个点采集一个点的方式对点云进行降采样。
print("Every 5th points are selected")uni_down_pcd = pcd.uniform_down_sample(every_k_points=5)o3d.visualization.draw_geometries([uni_down_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])
输出:
Every 5th points are selected选择性降采样
Section titled “选择性降采样”下面的辅助函数使用 select_by_index,它接收一个二值掩码,仅输出被选中的点。被选中的点和未被选中的点会被分别可视化。
def display_inlier_outlier(cloud, ind): inlier_cloud = cloud.select_by_index(ind) outlier_cloud = cloud.select_by_index(ind, invert=True)
print("Showing outliers (red) and inliers (gray): ") outlier_cloud.paint_uniform_color([1, 0, 0]) inlier_cloud.paint_uniform_color([0.8, 0.8, 0.8]) o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud], zoom=0.3412, front=[0.4257, -0.2125, -0.8795], lookat=[2.6172, 2.0475, 1.532], up=[-0.0694, -0.9768, 0.2024])统计离群点去除
Section titled “统计离群点去除”remove_statistical_outlier(统计离群点去除)会移除那些与自身邻居的距离相对于整个点云平均水平而言更远的点。它接收两个输入参数:
nb_neighbors,指定在计算给定点的平均距离时考虑多少个邻居。std_ratio,允许根据整个点云平均距离的标准差来设定阈值水平。该数值越低,滤波就越激进。
print("Statistical oulier removal")cl, ind = voxel_down_pcd.remove_statistical_outlier(nb_neighbors=20, std_ratio=2.0)display_inlier_outlier(voxel_down_pcd, ind)
输出:
Statistical oulier removalShowing outliers (red) and inliers (gray):半径离群点去除
Section titled “半径离群点去除”remove_radius_outlier(半径离群点去除)会移除那些在以其为中心、给定半径的球体内邻居数量过少的点。可以通过两个参数来针对你的数据调整该滤波器:
nb_points,用于选取球体内应包含的最少点数。radius,用于定义统计邻居时所使用球体的半径。
print("Radius oulier removal")cl, ind = voxel_down_pcd.remove_radius_outlier(nb_points=16, radius=0.05)display_inlier_outlier(voxel_down_pcd, ind)
输出:
Radius oulier removalShowing outliers (red) and inliers (gray):