Learning Open3D→Tutorial→基礎編→KDTree
Open3DはFLANNを使用してKDTreesを構築し、最寄りのものを高速に検索する。
search_knn_vector_3d
の使用search_radius_vector_3d
の使用注意: コードを走らせる環境に注意すること。TestData
ディレクトリがカレント(作業)ディレクトリからみて、祖先ディレクトリの下にあることを確認しよう
# 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("")
# (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]
としている)。これは、次の最近傍クエリーの前処理ステップである。
# (2)Find neighboring points
print("Paint the 1500th point red.")
pcd.colors[1500] = [1, 0, 0]
アンカーポイントとして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]
関数search_knn_vector_3d
は、アンカーポイントの最近傍点(その個数が変数k
にセットされる)のインデックスのリスト(変数idx
)を返す。 これらの隣接点は青色で塗られている。 pcd.colorsをnumpy配列に変換して、色属性に一括アクセスし、選択したすべてのポイントに青色([0,0,1]
)をブロードキャストしていることに注意。なお最初のインデックス(idx[0]
)はアンカーポイント自体であるため、スキップされている。
# (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]
でぬられている。
print("Visualize the point cloud.")
o3d.visualization.draw_geometries([pcd])
print("")
その結果は5番目の部分コードで表示される: (注意深く見ると、緑の中に赤い点がある。これがアンカーポイント)
Open3Dは、KNN検索search_knn_vector_3d
とRNN検索search_radius_vector_3d
の他に、ハイブリッド検索機能search_hybrid_vector_3d
を提供している。これは、 与えられた半径よりも小さいアンカーポイントまでの距離を持つk個の最近傍点を返す。 この関数は、KNN検索とRNN検索の基準を結合しており、いくつかの文献でRKNN検索と呼ばれている。 多くの実用的なケースではパフォーマンス上の利点があり、多くのOpen3D関数で頻繁に使用されている。