本日はOpen3Dを用いて、3D点群のダウンサンプリングを行うプログラムを紹介したいと思います。
ダウンサンプリングとは、入力された点を間引くことで点の数を減らす処理のことです。3D点群処理は、入力ファイルによっては膨大な点数の点群を扱う都合上、処理時間が膨大になる場合があります。
このような場合に、品質劣化を許容して、点を間引いて点の数を減らすことがあります。ここで使われるのがダウンサンプリングです。
Open3Dの環境構築に関しては、以前に環境構築の方法を紹介しましたので、以下の記事を参照してください。
Open3Dの点群ダウンサンプリング
リファレンスを読んだ限りでは「Uniform down sample」「Average voxel grid down sample」の2種類のダウンサンプリング法は少なくとも関数が用意されているようなので、この2つのダウンサンプリング法を紹介し、その後にプログラムを紹介します。
Uniform down sample(均一なダウンサンプリング)
こちらは点群のインデックスを使った間引きです。読み込まれた点群に対して、外部から与えられるサンプリングレートに従って点群を機械的に間引きます。
例えばサンプリングレートが10のとき、3D点群の入った配列から「1番目、11番目、21番目、31番目……10×k+1番目」の点を取り出し、他を破棄します。
メリットは、出力点数をコントロールしやすいことです。サンプリングレートが10であれば、点数は約1/10にコントロールされます。
デメリットは、点群の幾何構造を一切考慮せず配列の並びだけから間引くので、配列の並びによっては、一部の領域の点がごっそり消えてしまうことが起こり得る可能性があります。
Average voxel grid down sample(平均ボクセルグリッドを用いたダウンサンプリング)
こちらも3D点群のダウンサンプリング法としては著名なもので、ボクセルグリッドを用いる手法です。
この手法では3D点群が存在する3D空間内を、3Dの立方体であるボクセルで埋め尽くします。そして、各ボクセルの中に1個以上の点が存在するとき、これらの点の平均位置を計算し、その平均位置に点を置きなおします。
文章だとわかりづらいので、図で説明すると以下の通りです。

この手法のメリットは、出力される3D点群の解像度をコントロールしやすいことです。
3Dボクセルの中に最低1点が残るので、点と点の間隔が過剰に開いてしまうことなどが抑制できます。
一方、ダウンサンプリングを実施してみないと最終的な点数が何点になるかの予測が困難なので、一定の点数以内に収めたいという場合には、工夫が必要です。
3D点群データセット
今回は以下のG-PCDデータセットのポイントクラウドを用いて実験を行いたいと思いますので、もし試したい方がいましたら以下からダウンロードください。
外部サイト:G-PCD: Geometry Point Cloud Dataset ‒ MMSPG ‐ EPFL
Bunny、Cube、Sphere、Dragon、Vaseの色無し3D点群が提供されています。今回はこちらの3D点群ファイル(PLY形式)をOpen3Dで表示してみましょう。
3D点群ダウンサンプリングプログラム
環境
- OS:Windows 10
- Python 3.6.10
- Open3D ver. 0.10.0.1
ソースコード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import open3d as o3d
if __name__ == "__main__":
# Loading point cloud
print("Loading point cloud")
ptCloud = o3d.io.read_point_cloud("G-PCD\dragon.ply")
# Down-sampling by uniform down sample
ptCloudDS1 = ptCloud.uniform_down_sample(every_k_points=10)
# Down-sampling by average voxel grid
ptCloudDS2 = ptCloud.voxel_down_sample(voxel_size=0.05)
# Visualization
o3d.visualization.draw_geometries([ptCloud])
o3d.visualization.draw_geometries([ptCloudDS1])
o3d.visualization.draw_geometries([ptCloudDS2])
# Saving point cloud
print(ptCloud)
o3d.io.write_point_cloud("output.ply", ptCloud)
print(ptCloudDS1)
o3d.io.write_point_cloud("output_downsampled1.ply", ptCloudDS1)
print(ptCloudDS2)
o3d.io.write_point_cloud("output_downsampled2.ply", ptCloudDS2)
コードの解説
点群のダウンサンプリング(Uniform down sample)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Down-sampling by uniform down sample
ptCloudDS1 = ptCloud.uniform_down_sample(every_k_points=10)
上記の箇所でUniform down sampleを実現しています。
every_k_pointsに10を指定すると、入力点群に対して10個に1個の割合で点が選択されます。
そのため、この値を大きくすればするほど点の数が少なくなり、小さくすればするほど点の数が多くなります。
点群のダウンサンプリング(Average voxel grid down sample)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Down-sampling by average voxel grid
ptCloudDS2 = ptCloud.voxel_down_sample(voxel_size=0.05)
上記の箇所でボクセルグリッドを使ったダウンサンプリングを実現しています。
voxel_sizeがボクセルの一辺の長さを表しています。
このVoxel sizeの設定については注意が必要です。
今回は入力データの座標をチェックした上で0.05を設定していますが、入力する点群によっては位置座標が整数値(1,2,3,4,5……)で表現されている場合も多く、このときに0.05などの値を設定すると、全く点の数が減らないことも考えられます。
これは点と点の間隔(整数値)に対して、ボクセルサイズがあまりに小さくなることで、各ボクセルの中に最大でも1個ずつしか点が入らないというケースが起こり得るためです。
再掲しますが、下記の図の通り、同一ボクセルグリッドに2個以上の点が入るようにしないと点が間引かれないため、ダウンサンプリングされない可能性があります。

実行結果
コンソールに以下の結果が表示されます。上の行から順に「ダウンサンプリング前の点群の点数」「ダウンサンプリング(Uniform down sample)後の点数」「点群のダウンサンプリング(Average voxel grid down sample)後の点数」です。
geometry::PointCloud with 22998 points. geometry::PointCloud with 2300 points. geometry::PointCloud with 872 points.
ダウンサンプリングで点が減っていること、Uniform down sampleではevery_k_points=10を指定したので点が1/10程度になっていることを確認できます。
最後にウインドウに表示される点群を示します。点が正常に間引かれていることがわかります。
入力点群

ダウンサンプリング点群(Uniform down sample)

ダウンサンプリング点群(Average voxel grid down sample)

まとめ
本日はOpen3Dを用いて、2種類の方法で点をダウンサンプリングするプログラムを紹介しました。
処理時間が大きくなる処理の前段等でダウンサンプリングを挟むことで、品質劣化は発生しますが処理を軽量化することが可能となります。