Learning Open3D→Tutorial→基礎編→ポイントクラウド(点群)
ポイントクラウド(点群)の使い方
参考: ポイントクラウドの可視化プログラムとしてPCL提供のもの以外に、http://www.danielgm.net/cc/ がある。Ubuntuではsnap install cloudcompare
によってインストールが可能。`cloudcompare.CloudCompare'で起動 (紹介記事: http://www.pointcloud.jp/blog_n23/)
本チュートリアルでは、ポイントクラウドの基本的な使い方をしめす。
注意: コードを走らせる環境に注意すること。TestData
ディレクトリがカレント(作業)ディレクトリからみて、祖先ディレクトリの下にあることを確認しよう
# examples/Python/Basic/pointcloud.py
import numpy as np
import open3d as o3d
if __name__ == "__main__":
# Visualize Point Cloud
print("Load a ply point cloud, print it, and render it")
pcd = o3d.io.read_point_cloud("../../TestData/fragment.ply")
print(pcd)
print(np.asarray(pcd.points))
o3d.visualization.draw_geometries([pcd])
# Voxel downsampling
print("Downsample the point cloud with a voxel of 0.05")
downpcd = pcd.voxel_down_sample(voxel_size=0.05)
o3d.visualization.draw_geometries([downpcd])
# Vertex normal estimation
print("Recompute the normal of the downsampled point cloud")
downpcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(
radius=0.1, max_nn=30))
o3d.visualization.draw_geometries([downpcd])
# Access estimated vertex normal
print("Print a normal vector of the 0th point")
print(downpcd.normals[0])
print("Print the normal vectors of the first 10 points")
print(np.asarray(downpcd.normals)[:10, :])
print("")
# Crop point cloud
print("Load a polygon volume and use it to crop the original point cloud")
vol = o3d.visualization.read_selection_polygon_volume(
"../../TestData/Crop/cropped.json")
chair = vol.crop_point_cloud(pcd)
o3d.visualization.draw_geometries([chair])
print("")
# Paint point cloud
print("Paint chair")
chair.paint_uniform_color([1, 0.706, 0])
o3d.visualization.draw_geometries([chair])
print("")
はじめに、ポイントクラウド(点群)ファイルを読み込み、それを可視化する方法を紹介
examples/Python/Basic/pointcloud.py
の最初の部分コード
# Visualize Point Cloud
print("Load a ply point cloud, print it, and render it")
pcd = o3d.io.read_point_cloud("./TestData/fragment.ply")
print(pcd)
print(np.asarray(pcd.points))
o3d.visualization.draw_geometries([pcd])
read_point_cloud
関数はファイルからポイントクラウドを読み込み、その拡張子に基づいてデコードを試みる。扱える拡張子は: pcd, ply, xyz, xyzrgb, xyzn, pts.
draw_geometries
は ポイントクラウドを可視化する。マウスを用いて、いろいろな視点からその幾何形状をみることができる。
みかけは密度のある曲面のようにみえるが、実際にはsurfles(曲面要素)としてレンダリングされたものである。GUIによりいろいろなキーボード関数がサポートされている。そのひとつは、-
キーで点群数を小さくする。これを何回か押してみると次のように見えるだろう;
-- Mouse view control --
Left button + drag : Rotate. (回転)
Ctrl + left button + drag : Translate. (平行移動)
Wheel : Zoom in/out. (ズームイン・アウト)
-- Keyboard view control --
[/] : Increase/decrease field of view.
R : Reset view point.
Ctrl/Cmd + C : Copy current view status into the clipboard.
Ctrl/Cmd + V : Paste view status from clipboard.
-- General control --
Q, Esc : Exit window. (終了)
H : Print help message. (ヘルプメッセージの表示)
P, PrtScn : Take a screen capture. (スクリーンキャプチャ)
D : Take a depth capture. (深さキャプチャ)
O : Take a capture of current rendering settings. (現在のレンダリング設定のキャプチャ)
-- Render mode control --
L : Turn on/off lighting.
+/- : Increase/decrease point size.
N : Turn on/off point cloud normal rendering.
S : Toggle between mesh flat shading and smooth shading.
W : Turn on/off mesh wireframe.
B : Turn on/off back face rendering.
I : Turn on/off image zoom in interpolation.
T : Toggle among image render:
no stretch / keep ratio / freely stretch.
-- Color control --
0..4,9 : Set point cloud color option.
0 - Default behavior, render point color.
1 - Render point color.
2 - x coordinate as color.
3 - y coordinate as color.
4 - z coordinate as color.
9 - normal as color.
Ctrl + 0..4,9: Set mesh color option.
0 - Default behavior, render uniform gray color.
1 - Render point color.
2 - x coordinate as color.
3 - y coordinate as color.
4 - z coordinate as color.
9 - normal as color.
Shift + 0..4 : Color map options.
0 - Gray scale color.
1 - JET color map.
2 - SUMMER color map.
3 - WINTER color map.
4 - HOT color map.
ボクセル(voxel)の説明: https://ja.wikipedia.org/wiki/%E3%83%9C%E3%82%AF%E3%82%BB%E3%83%AB
ボクセルのダウンサンプリングは、通常のボクセル・グリッドを使用して、入力点群から一様にダウンサンプリングされたポイントクラウド(点群)を作成する。 これは、多くのポイント・クラウド処理タスクの前処理ステップとしてよく使用される。 アルゴリズムは2つのステップで動作する。
次はexamples/Python/Basic/pointcloud.py
の2番めの部分コード
# Voxel downsampling
print("Downsample the point cloud with a voxel of 0.05")
downpcd = pcd.voxel_down_sample(voxel_size=0.05)
o3d.visualization.draw_geometries([downpcd])
ダウンサンプリングした結果は以下のようなもの:
ポイントクラウドに対するもうひとつの基本操作は、点法線推定(point normal estimation)である.
次はexamples/Python/Basic/pointcloud.pyの3番めの部分コード
# Vertex normal estimation
print("Recompute the normal of the downsampled point cloud")
downpcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(
radius=0.1, max_nn=30))
o3d.visualization.draw_geometries([downpcd])
estimate_normals
はすべての点の法線を計算する。 この関数は共分散分析を用いて隣接点を見つけ、隣接点の主軸を計算する。
この関数は、KDTreeSearchParamHybrid
クラスのインスタンスを引数として取る。 radius = 0.1
とmax_nn = 30
という2つの重要な引数は、検索半径と最大最近傍を指定するもの。 これにより10cmの探索半径を持ち、計算時間を節約するため最大30個の近傍しか考慮しない
共分散分析アルゴリズムは、法線の候補として2つの互いに反対方向のベクトルを生成する。 ジオメトリのグローバルな構造を知らなければ、どちらも正しい可能性がある。
これは、法線方向問題として知られている問題である。 Open3Dは、法線が存在する場合、元の法線と揃うように法線の方向付けを試みる。 それ以外の場合、Open3Dはランダムな推測を行う。 方向が重要な場合は、orient_normals_to_align_with_direction
やorient_normals_towards_camera_location
などの方向付け関数を呼び出す必要がある。
draw_geometries
を使用して点群を可視化し、n
を押して点の法線を表示する。 -
キーと+
キーを使用して法線の長さを制御できる。
推定法線ベクトル(estimated normal vector)は、downpcd
の法線変数によって取得できる。
次はexamples/Python/Basic/pointcloud.pyの4番めの部分コード
print("Print a normal vector of the 0th point")
print(downpcd.normals[0])
Print a normal vector of 0th point
[-0.27566603 -0.89197839 -0.35830543]
他の変数を調べるには、help(downpcd)を使用すること。 法線ベクトルは、np.asarray
を使用してnumpy
配列として変換できる:
print("Print the normal vectors of the first 10 points")
print(np.asarray(downpcd.normals)[:10, :])
これにより最初の10個の点の法線ベクトルが表示される:
[[-0.27566603 -0.89197839 -0.35830543]
[-0.00694405 -0.99478075 -0.10179902]
[-0.00399871 -0.99965423 -0.02598917]
[-0.46344316 -0.68643798 -0.56037785]
[-0.43476205 -0.62438493 -0.64894177]
[-0.51440078 -0.56093481 -0.6486478 ]
[-0.27498453 -0.67317361 -0.68645524]
[-0.00327304 -0.99977409 -0.02100143]
[-0.01464332 -0.99960281 -0.02407874]]
numpy
配列に関する他の例については、Working with NumPy
の項を参照してほしい。
read_selection_polygon_volume
はポリゴン選択領域を指定するJSONファイルを読み込む。 vol.crop_point_cloud(pcd)
は点群をフィルターする。 以下を実行すると椅子だけが選択されて残る。
次はexamples/Python/Basic/pointcloud.pyの5番めの部分コード
print("Load a polygon volume and use it to crop the original point cloud")
vol = o3d.visualization.read_selection_polygon_volume(
"./TestData/Crop/cropped.json")
chair = vol.crop_point_cloud(pcd)
o3d.visualization.draw_geometries([chair])
print("")
./TestData/Crop/cropped.json ファイルの内容:
{
"axis_max" : 4.022921085357666,
"axis_min" : -0.76341366767883301,
"bounding_polygon" :
[
[ 2.6509309513852526, 0.0, 1.6834473132326844 ],
[ 2.5786428246917148, 0.0, 1.6892074266735244 ],
[ 2.4625790337552154, 0.0, 1.6665777078297999 ],
[ 2.2228544982251655, 0.0, 1.6168160446813649 ],
[ 2.166993206001413, 0.0, 1.6115495157201662 ],
[ 2.1167895865303286, 0.0, 1.6257706054969348 ],
[ 2.0634657721747383, 0.0, 1.623021658624539 ],
[ 2.0568612343437236, 0.0, 1.5853892911207643 ],
[ 2.1605399001237027, 0.0, 0.96228993255083017 ],
[ 2.1956669387205228, 0.0, 0.95572746049785073 ],
[ 2.2191318790575583, 0.0, 0.88734449982108754 ],
[ 2.2484881847925919, 0.0, 0.87042807267013633 ],
[ 2.6891234157295827, 0.0, 0.94140677988967603 ],
[ 2.7328692490470647, 0.0, 0.98775740674840251 ],
[ 2.7129337547575547, 0.0, 1.0398850034649203 ],
[ 2.7592174072415405, 0.0, 1.0692940558509485 ],
[ 2.7689216419453428, 0.0, 1.0953914441371593 ],
[ 2.6851455625455669, 0.0, 1.6307334122162018 ],
[ 2.6714776099981239, 0.0, 1.675524657088997 ],
[ 2.6579576128816544, 0.0, 1.6819127849749496 ]
],
"class_name" : "SelectionPolygonVolume",
"orthogonal_axis" : "Y",
"version_major" : 1,
"version_minor" : 0
}
実行結果の画像:
paint_uniform_color
は一様な色で全ての点に色付けする。色はRGB空間 [0, 1] の範囲で指定する。
下記のプログラム(examples/Python/Basic/pointcloud.pyの6番めの部分コード)の実行結果:
print("Paint chair")
chair.paint_uniform_color([1, 0.706, 0])
o3d.visualization.draw_geometries([chair])
print("")