Learning Open3DTutorial基礎編→ポイントクラウド(点群)

Point Cloud

ポイントクラウド(点群)の使い方

参考: ポイントクラウドの可視化プログラムとしてPCL提供のもの以外に、http://www.danielgm.net/cc/ がある。Ubuntuではsnap install cloudcompare によってインストールが可能。`cloudcompare.CloudCompare'で起動 (紹介記事: http://www.pointcloud.jp/blog_n23/)

本チュートリアルでは、ポイントクラウドの基本的な使い方をしめす。

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

In [19]:
# 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("")
Load a ply point cloud, print it, and render it
geometry::PointCloud with 196133 points.
[[0.65234375 0.84686458 2.37890625]
 [0.65234375 0.83984375 2.38430572]
 [0.66737998 0.83984375 2.37890625]
 ...
 [2.00839925 2.39453125 1.88671875]
 [2.00390625 2.39488506 1.88671875]
 [2.00390625 2.39453125 1.88793314]]
Downsample the point cloud with a voxel of 0.05
Recompute the normal of the downsampled point cloud
Print a normal vector of the 0th point
[-0.21838377 -0.94240442 -0.25334252]
Print the normal vectors of the first 10 points
[[-0.21838377 -0.94240442 -0.25334252]
 [-0.04374285 -0.94373358 -0.32780099]
 [-0.00694405 -0.99478075 -0.10179902]
 [-0.46344316 -0.68643798 -0.56037785]
 [-0.43476205 -0.62438493 -0.64894177]
 [-0.27498453 -0.67317361 -0.68645524]
 [ 0.01316083 -0.99964286 -0.02325814]
 [-0.01038945 -0.99968858 -0.02268921]
 [-0.00816546 -0.99965616 -0.02491762]
 [-0.13075895 -0.94176382 -0.30981124]]

Load a polygon volume and use it to crop the original point cloud

Paint chair


Visualize point cloud

はじめに、ポイントクラウド(点群)ファイルを読み込み、それを可視化する方法を紹介

examples/Python/Basic/pointcloud.pyの最初の部分コード

In [ ]:
    # 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 は ポイントクラウドを可視化する。マウスを用いて、いろいろな視点からその幾何形状をみることができる。 http://www.open3d.org/docs/release/_images/scene.png

みかけは密度のある曲面のようにみえるが、実際にはsurfles(曲面要素)としてレンダリングされたものである。GUIによりいろいろなキーボード関数がサポートされている。そのひとつは、- キーで点群数を小さくする。これを何回か押してみると次のように見えるだろう; http://www.open3d.org/docs/release/_images/scene_small.png

注意:

hキーを押せば以下に示すリストがえられる。詳しい情報は、可視化可視化のカスタム化の項を参照。

-- 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 downsampling

ボクセル(voxel)の説明: https://ja.wikipedia.org/wiki/%E3%83%9C%E3%82%AF%E3%82%BB%E3%83%AB

ボクセルのダウンサンプリングは、通常のボクセル・グリッドを使用して、入力点群から一様にダウンサンプリングされたポイントクラウド(点群)を作成する。 これは、多くのポイント・クラウド処理タスクの前処理ステップとしてよく使用される。 アルゴリズムは2つのステップで動作する。

  1. ポイントをボクセルに入れる。
  2. 占有された各ボクセルは、内部のすべての点を平均化することによって正確な1点を生成する。

次はexamples/Python/Basic/pointcloud.pyの2番めの部分コード

In [ ]:
    # 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])

ダウンサンプリングした結果は以下のようなもの: http://www.open3d.org/docs/release/_images/downsampled.png

Vertex normal estimation

ポイントクラウドに対するもうひとつの基本操作は、点法線推定(point normal estimation)である.

次はexamples/Python/Basic/pointcloud.pyの3番めの部分コード

In [ ]:
    # 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.1max_nn = 30という2つの重要な引数は、検索半径と最大最近傍を指定するもの。 これにより10cmの探索半径を持ち、計算時間を節約するため最大30個の近傍しか考慮しない

共分散分析アルゴリズムは、法線の候補として2つの互いに反対方向のベクトルを生成する。 ジオメトリのグローバルな構造を知らなければ、どちらも正しい可能性がある。 これは、法線方向問題として知られている問題である。 Open3Dは、法線が存在する場合、元の法線と揃うように法線の方向付けを試みる。 それ以外の場合、Open3Dはランダムな推測を行う。 方向が重要な場合は、orient_normals_to_align_with_directionorient_normals_towards_camera_locationなどの方向付け関数を呼び出す必要がある。

draw_geometriesを使用して点群を可視化し、nを押して点の法線を表示する。 -キーと+キーを使用して法線の長さを制御できる。 http://www.open3d.org/docs/release/_images/downsampled_normal.png

Access estimated vertex normal

推定法線ベクトル(estimated normal vector)は、downpcd の法線変数によって取得できる。

次はexamples/Python/Basic/pointcloud.pyの4番めの部分コード

In [ ]:
    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配列として変換できる:

In [ ]:
    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の項を参照してほしい。

Crop point cloud

read_selection_polygon_volume はポリゴン選択領域を指定するJSONファイルを読み込む。 vol.crop_point_cloud(pcd)は点群をフィルターする。 以下を実行すると椅子だけが選択されて残る。

次はexamples/Python/Basic/pointcloud.pyの5番めの部分コード

In [ ]:
    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
}

実行結果の画像: http://www.open3d.org/docs/release/_images/crop.png

Paint point cloud

paint_uniform_color は一様な色で全ての点に色付けする。色はRGB空間 [0, 1] の範囲で指定する。 下記のプログラム(examples/Python/Basic/pointcloud.pyの6番めの部分コード)の実行結果: http://www.open3d.org/docs/release/_images/crop_color.png

In [ ]:
    print("Paint chair")
    chair.paint_uniform_color([1, 0.706, 0])
    o3d.visualization.draw_geometries([chair])
    print("")

Previous:ファイルの入出力            Next:メッシュ