KDTree

Open3DはFLANNを使用してKDTreesを構築し、最寄りのものを高速に検索する。

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

In [4]:
# examples/Python/Basic/kdtree.py

import numpy as np
import open3d as o3d

if __name__ == "__main__":
    # (1)Build KDTree from point cloud
    print("Testing kdtree in open3d ...")
    print("Load a point cloud and paint it gray.")
    pcd = o3d.io.read_point_cloud("../../TestData/Feature/cloud_bin_0.pcd")
    pcd.paint_uniform_color([0.5, 0.5, 0.5])
    pcd_tree = o3d.geometry.KDTreeFlann(pcd)
    # (2)Find neighboring points
    print("Paint the 1500th point red.")
    pcd.colors[1500] = [1, 0, 0]
    # (3) Using search_knn_vector_3d
    print("Find its 200 nearest neighbors, paint blue.")
    [k, idx, _] = pcd_tree.search_knn_vector_3d(pcd.points[1500], 200)
    np.asarray(pcd.colors)[idx[1:], :] = [0, 0, 1]
    # (4) Using search_radius_vector_3d
    print("Find its neighbors with distance less than 0.2, paint green.")
    [k, idx, _] = pcd_tree.search_radius_vector_3d(pcd.points[1500], 0.2)
    np.asarray(pcd.colors)[idx[1:], :] = [0, 1, 0]
    # (5) Visualization
    print("Visualize the point cloud.")
    o3d.visualization.draw_geometries([pcd])
    print("")
Testing kdtree in open3d ...
Load a point cloud and paint it gray.
Paint the 1500th point red.
Find its 200 nearest neighbors, paint blue.
Find its neighbors with distance less than 0.2, paint green.
Visualize the point cloud.

Build KDTree from point cloud

ポイントクラウドからKDTreeを構築する

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

In [ ]:
    # (1)Build KDTree from point cloud
    print("Testing kdtree in open3d ...")
    print("Load a point cloud and paint it gray.")
    pcd = o3d.io.read_point_cloud("../../TestData/Feature/cloud_bin_0.pcd")
    pcd.paint_uniform_color([0.5, 0.5, 0.5])
    pcd_tree = o3d.geometry.KDTreeFlann(pcd)

このスクリプトは点群を読み取り、KDTreeを構築する。(ここではすべての点を灰色[0.5, 0.5, 0.5]としている)。これは、次の最近傍クエリーの前処理ステップである。

Find neighboring points

隣接ポイントを見つける

examples/Python/Basic/kdtree.pyの2番めの部分コード:

In [ ]:
    # (2)Find neighboring points
    print("Paint the 1500th point red.")
    pcd.colors[1500] = [1, 0, 0]

アンカーポイントとして1500番目のポイントを選んで赤く([1,0,0])塗る。

Using search_knn_vector_3d

search_knn_vector_3dの使用

examples/Python/Basic/kdtree.pyの3番めの部分コード:

In [ ]:
    # (3) Using search_knn_vector_3d
    print("Find its 200 nearest neighbors, paint blue.")
    [k, idx, _] = pcd_tree.search_knn_vector_3d(pcd.points[1500], 200)
    np.asarray(pcd.colors)[idx[1:], :] = [0, 0, 1]

関数search_knn_vector_3dは、アンカーポイントの最近傍点(その個数が変数kにセットされる)のインデックスのリスト(変数idx)を返す。 これらの隣接点は青色で塗られている。 pcd.colorsをnumpy配列に変換して、色属性に一括アクセスし、選択したすべてのポイントに青色([0,0,1])をブロードキャストしていることに注意。なお最初のインデックス(idx[0])はアンカーポイント自体であるため、スキップされている。

Using search_radius_vector_3d

search_radius_vector_3dの使用

examples/Python/Basic/kdtree.pyの4番めの部分コード:

In [ ]:
    # (4) Using search_radius_vector_3d
    print("Find its neighbors with distance less than 0.2, paint green.")
    [k, idx, _] = pcd_tree.search_radius_vector_3d(pcd.points[1500], 0.2)
    np.asarray(pcd.colors)[idx[1:], :] = [0, 1, 0]

関数search_knn_vector_3dと同様に、関数search_radius_vector_3dを使用して、アンカーポイントから指定された半径(この場合は$0.2$)以内にあるすべてのポイント(個数はk)を検索することができる。 これらの点(変数idxがそのリスト)は緑色[0,1,0]でぬられている。

In [ ]:
    print("Visualize the point cloud.")
    o3d.visualization.draw_geometries([pcd])
    print("")

その結果は5番目の部分コードで表示される: (注意深く見ると、緑の中に赤い点がある。これがアンカーポイント)

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

注意:

Open3Dは、KNN検索search_knn_vector_3dとRNN検索search_radius_vector_3dの他に、ハイブリッド検索機能search_hybrid_vector_3dを提供している。これは、 与えられた半径よりも小さいアンカーポイントまでの距離を持つk個の最近傍点を返す。 この関数は、KNN検索とRNN検索の基準を結合しており、いくつかの文献でRKNN検索と呼ばれている。 多くの実用的なケースではパフォーマンス上の利点があり、多くのOpen3D関数で頻繁に使用されている。