Learning Open3DTutorial上級編→ポイントクラウド外れ値除去

Point cloud outlier removal

ポイントクラウド外れ値除去

スキャナーを用いてデータ収集するとき、ポイントクラウドにノイズと人工物(アーティファクト)が含まれていることがある。このチュートリアルでは、外れ値の削除機能について説明する。

注意: コードを走らせる環境に注意すること。TestDataディレクトリがカレント(作業)ディレクトリからみて、祖先ディレクトリの下にあることを確認しよう

In [2]:
# examples/Python/Advanced/outlier_removal.py

import open3d as o3d


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


if __name__ == "__main__":
    # (1) Load a ply point cloud, print it, and render it
    print("Load a ply point cloud, print it, and render it")
    pcd = o3d.io.read_point_cloud("../../TestData/ICP/cloud_bin_2.pcd")
    o3d.visualization.draw_geometries([pcd])
    # (2) Downsample the point cloud with a voxel
    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])
    # (3) Every 5th points are selected
    print("Every 5th points are selected")
    uni_down_pcd = pcd.uniform_down_sample(every_k_points=5)
    o3d.visualization.draw_geometries([uni_down_pcd])
    # (4) Statistical oulier removal
    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)
    # (5) Radius oulier removal
    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)
Load a ply point cloud, print it, and render it
Downsample the point cloud with a voxel of 0.02
Every 5th points are selected
Statistical oulier removal
Showing outliers (red) and inliers (gray): 
Radius oulier removal
Showing outliers (red) and inliers (gray): 

Prepare input data

入力データの前処理

voxel_downsample関数を使用して、点群をロードし、ダウン・サンプリングする:

examples/Python/Advanced/outlier_removal.pyの最初の部分コードと2番め

In [ ]:
    # (1) Load a ply point cloud, print it, and render it
    print("Load a ply point cloud, print it, and render it")
    pcd = o3d.io.read_point_cloud("../../TestData/ICP/cloud_bin_2.pcd")
    o3d.visualization.draw_geometries([pcd])
    
    # (2) Downsample the point cloud with a voxel
    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])

http://www.open3d.org/docs/release/_images/voxel_down_sample.png

比較のために、uniform_down_sampleは、n番目ごとにポイントを収集して、ポイント・クラウドをダウン・サンプリングできる。

examples/Python/Advanced/outlier_removal.pyの3番目の部分コード

In [ ]:
    # (3) Every 5th points are selected
    print("Every 5th points are selected")
    uni_down_pcd = pcd.uniform_down_sample(every_k_points=5)
    o3d.visualization.draw_geometries([uni_down_pcd])

Select down sample

ダウンサンプリングの選択

ここで定義した関数display_inlier_outlierは、二値マスクを取って選択した点のみを出力するselect_down_sampleを使っている。そして選択された点と選択されなかった点とを別々の色で視覚化する(残すほうが灰色、外れ値としたものが赤色)。

examples/Python/Advanced/outlier_removal.pyの最初の関数定義

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

Statistical outlier removal

統計的外れ値除去

examples/Python/Advanced/outlier_removal.pyの4番目の部分コード

In [ ]:
    # (4) Statistical oulier removal
    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)

statistics_outlier_removalは、ポイントクラウドの平均と比較して、近傍から離れた点を削除する。これは次の2つの入力パラメーターを取る:

  • nb_neighborsにより、点の平均距離の計算に考慮すべき近隣点の数を指定できる
  • std_ratioにより、点群全体の平均距離の標準偏差に基づいて閾値レベルを設定できる。この数値が低いほど、フィルターはより多くの点を削減することになる。

残すほうが灰色、外れ値としたものが赤色

http://www.open3d.org/docs/release/_images/statistical_outlier_removal.png

Radius outlier removal

幾何的外れ値除去

examples/Python/Advanced/outlier_removal.pyの4番目の部分コード

In [ ]:
    # (5) Radius oulier removal
    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_outlier_removalは、指定された半径の球内に隣接点が少ない点を削除する。これは次の2つのパラメーターにより削除方法を調整できる:

  • nb_pointsにより球体に含める最小個数の点数を指定できる
  • radiusは、近傍点数の数え上げに使う球の半径を指定する

残すほうが灰色、外れ値としたものが赤色

http://www.open3d.org/docs/release/_images/radius_outlier_removal.png