Point cloud outlier removal

When collecting data from scanning devices, it happens that the point cloud contains noise and artifact that one would like to remove. This tutorial address outlier removal feature.

 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# examples/Python/Advanced/outlier_removal.py

from open3d import *

def display_inlier_outlier(cloud, ind):
    inlier_cloud = select_down_sample(cloud, ind)
    outlier_cloud = select_down_sample(cloud, 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])
    draw_geometries([inlier_cloud, outlier_cloud])


if __name__ == "__main__":

    print("Load a ply point cloud, print it, and render it")
    pcd = read_point_cloud("../../TestData/ICP/cloud_bin_2.pcd")
    draw_geometries([pcd])

    print("Downsample the point cloud with a voxel of 0.02")
    voxel_down_pcd = voxel_down_sample(pcd, voxel_size = 0.02)
    draw_geometries([voxel_down_pcd])

    print("Every 5th points are selected")
    uni_down_pcd = uniform_down_sample(pcd, every_k_points = 5)
    draw_geometries([uni_down_pcd])

    print("Statistical oulier removal")
    cl,ind = statistical_outlier_removal(voxel_down_pcd,
            nb_neighbors=20, std_ratio=2.0)
    display_inlier_outlier(voxel_down_pcd, ind)

    print("Radius oulier removal")
    cl,ind = radius_outlier_removal(voxel_down_pcd,
            nb_points=16, radius=0.05)
    display_inlier_outlier(voxel_down_pcd, ind)

Prepare input data

A point cloud is loaded and downsampled using voxel_downsample.

21
22
23
24
25
26
27
    print("Load a ply point cloud, print it, and render it")
    pcd = read_point_cloud("../../TestData/ICP/cloud_bin_2.pcd")
    draw_geometries([pcd])

    print("Downsample the point cloud with a voxel of 0.02")
    voxel_down_pcd = voxel_down_sample(pcd, voxel_size = 0.02)
    draw_geometries([voxel_down_pcd])
../../_images/voxel_down_sample.png

For comparison, uniform_down_sample can downsample point cloud by collecting every n-th points.

29
30
31
    print("Every 5th points are selected")
    uni_down_pcd = uniform_down_sample(pcd, every_k_points = 5)
    draw_geometries([uni_down_pcd])
../../_images/uniform_down_sample.png

Select down sample

The helper function uses select_down_sample that takes binary mask to output only the selected points. The selected points and the non-selected points are visualized.

 9
10
11
12
13
14
15
16
def display_inlier_outlier(cloud, ind):
    inlier_cloud = select_down_sample(cloud, ind)
    outlier_cloud = select_down_sample(cloud, 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])
    draw_geometries([inlier_cloud, outlier_cloud])

Statistical outlier removal

33
34
35
36
    print("Statistical oulier removal")
    cl,ind = statistical_outlier_removal(voxel_down_pcd,
            nb_neighbors=20, std_ratio=2.0)
    display_inlier_outlier(voxel_down_pcd, ind)

statistical_outlier_removal removes points that are further away from their neighbors compared to the average for the point cloud. It takes two input parameters:

  • nb_neighbors allows to specify how many neighbors are taken into account in order to calculate the average distance for a given point.

  • std_ratio allows to set the threshold level based on the standard deviation of the average distances across the point cloud. The lower this number the more aggressive the filter will be.

../../_images/statistical_outlier_removal.png

Radius outlier removal

38
39
40
41
    print("Radius oulier removal")
    cl,ind = radius_outlier_removal(voxel_down_pcd,
            nb_points=16, radius=0.05)
    display_inlier_outlier(voxel_down_pcd, ind)

radius_outlier_removal removes points that have few neighbors in a given sphere around them. Two parameters can be used to tune the filter to your data:

  • nb_points lets you pick the minimum amount of points that the sphere should contain

  • radius defines the radius of the sphere that will be used for counting the neighbors.

../../_images/radius_outlier_removal.png