Nanoflannは、さまざまなトポロジーを持つデータセットのKDツリーを構築するためのC ++ 11ヘッダーのみのライブラリです:R 2 、R 3 (ポイントクラウド)、SO(2)およびSO(3)(2Dおよび3D回転グループ)。おおよそのNNのサポートは提供されていません。 Nanoflannは、コンパイルまたはインストールを必要としません。コードに#include <nanoflann.hpp>が必要です。
このライブラリは、Marius MujaとDavid G. LoweによるFlann Libraryのフォークであり、MRPTの児童プロジェクトとして生まれました。元のライセンス条件に従って、 NanoflannはBSDライセンスの下に配布されます。バグについては、問題ボタンまたはフォークを使用してプルリクエストを開きます。
引用:
@misc{blanco2014nanoflann,
title = {nanoflann: a {C}++ header-only fork of {FLANN}, a library for Nearest Neighbor ({NN}) with KD-trees},
author = {Blanco, Jose Luis and Rai, Pranjal Kumar},
howpublished = {url{https://github.com/jlblancoc/nanoflann}},
year = {2014}
}
プロジェクトの変更のリストについては、リリースChangelogを参照してください。
include/nanoflann.hppファイルを使用します。$ sudo apt install libnanoflann-devnanoflann HomeBrewにインストールできます。 $ brew install brewsci/science/nanoflann$ brew tap brewsci/science
$ brew install nanoflann$ sudo port install nanoflannbrew install homebrew/science/nanoflannNanoflann自体はコンパイルする必要はありませんが、次の例とテストを作成できます。
$ sudo apt-get install build-essential cmake libgtest-dev libeigen3-dev
$ mkdir build && cd build && cmake ..
$ make && make testDoxygenドキュメントを閲覧します。
重要な注意: L2の規範が使用されている場合、検索半径とすべて通過および返された距離が実際には四角い距離であることに注意してください。
knnSearch()およびradiusSearch() :pointcloud_kdd_radius.cppEigen::Matrix<> :matrix_example.cppstd::vector<std::vector<T> >またはstd::vector<Eigen::VectorXd> :vector_of_vectors_example.cppで直接ルックアップpkg-configを介した使用のためのMakefileを使用します(たとえば、「インストール」を行った後、またはubuntuリポジトリからインストールした後):example_with_pkgconfig/mrpt-gui sudo apt install libmrpt-gui-dev必要です。
実行時間効率:
flann Libraryの力は、異なるANNアルゴリズムを選択する可能性に由来しています。この柔軟性のコストは、(状況によっては)ランタイムペナルティを課す純粋な仮想方法の宣言です。 nanoflannでは、これらの仮想方法はすべて、不思議な繰り返しテンプレートパターン(CRTP)とインラインドメソッドの組み合わせに置き換えられました。これらははるかに高速です。radiusSearch()の場合、半径内のポイント数を決定し、データを取得するために再度電話をかけるために呼び出しを行う必要はありません。出力データにSTLコンテナを使用することにより、コンテナは自動的にサイズ変更されます。nanoflann使用すると、ユーザーは、利用可能な場合は、再構成を避けるために、データの事前に計算された境界ボックスを提供できます。intからsize_tに変換されており、非常に大きなデータセットを処理するときに制限を削除します。メモリ効率:KD -Treeインデックスを構築する前に、データセット全体のカスタムflannのようなマトリックスにコピーする代わりに、 nanoflannクラスで実装する必要があるアダプターインターフェイスを介してデータに直接アクセスできます。
詳細については、以下の例またはnanoflann :: kdtreesingleindexadaptor <>のC ++ APIを参照してください。
::knnSearch()query_point[0:dim-1]にnum_closestの最近隣人を見つけます。それらのインデックスは、結果オブジェクト内に保存されます。使用法コードの例を参照してください。::radiusSearch()query_point[0:dim-1]に見つけます。出力はペアのベクトルとして与えられ、その最初の要素はポイントインデックス、2番目は対応する距離です。使用法コードの例を参照してください。::radiusSearchCustomCallback()Eigen::Matrix<>クラス(マトリックスとベクトルのベクトル)で直接作業します。R^N :ユークリッドスペース:L1 (マンハッタン)L2 (SSE2の最適化を支持する四角ユークリッド規範)。L2_Simple (ポイントクラウドなどの低次元データセット用のユークリッドノルムの正方形の規範)。SO(2) :2D回転グループmetric_SO2 :絶対角の違い。SO(3) :3D回転グループ(将来のリリースで提供されるより良いサポート)metric_SO3 :Quaternions間の内製品。プロジェクトにnanoflann.hppファイルを直接ドロップできます。または、Cmake標準メソッドも利用できます。
CMAKE_INSTALL_PREFIX適切なパスに設定してから、 make install (Linux、OSX)を実行するか、 INSTALLターゲット(Visual Studio)を構築します。 # Find nanoflannConfig.cmake:
find_package (nanoflann)
add_executable (my_project test .cpp)
# Make sure the include path is used:
target_link_libraries (my_project nanoflann::nanoflann)conanの使用nanoflann用に事前に構築されたバイナリをインストールしたり、Conanを使用してソースから構築したりできます。次のコマンドを使用して、最新バージョンをインストールします。
$ conan install --requires= " nanoflann/[*] " --build=missingコナンの使用方法に関する詳細な手順については、コナンのドキュメントを参照してください。
nanoflann・コナンのレシピは、コナンのメンテナーとコミュニティの貢献者によって最新の状態に保たれています。バージョンが古くなっている場合は、ConancenterIndexリポジトリで問題を作成するか、リクエストをプルしてください。
vcpkgを使用しますVCPKG依存関係マネージャーを使用してNanoflannをダウンロードしてインストールできます。
$ git clone https://github.com/Microsoft/vcpkg.git
$ cd vcpkg
$ ./bootstrap-vcpkg.sh
$ ./vcpkg integrate install
$ ./vcpkg install nanoflannVCPKGのNanoflannポートは、Microsoftチームのメンバーとコミュニティの貢献者によって最新の状態に保たれています。バージョンが古くなっている場合は、VCPKGリポジトリに問題を作成するか、リクエストをプルしてください。
NANOFLANN_FIRST_MATCH :定義され、2つのポイントが同じ距離を持っている場合、最も低いインデックスのあるポイントが最初に返されます。それ以外の場合、特定の順序はありません。NANOFLANN_NO_THREADS :定義されている場合、マルチスレッド機能は無効になるため、pthreadsとリンクせずにライブラリを使用できます。複数のスレッドを使用しようとすると、例外がスローされます。 KDTreeSingleIndexAdaptorParams::leaf_max_sizeKD-Treeは...まあ、木:-)です。そのため、ルートノード、中間ノードのセット、最後に、子供のない「リーフ」ノードがあります。
ポイント(または、適切に、ポイントインデックス)は、リーフノードにのみ保存されます。各葉には、そのポイントがその範囲内に収まるリストが含まれています。
ツリーを構築する間、ノードは、内部のポイントの数が等か何らかのしきい値を下回るまで再帰的に分割されます。それはleaf_max_sizeです。クエリを実行している間、「ツリーアルゴリズム」は葉のノードを選択し、葉のすべてのクエリに最も近いポイントに線形検索(1つ)を実行することで終了します。
したがって、 leaf_max_sizeトレードオフとして設定する必要があります。
選択する番号は、実際にアプリケーションとプロセッサキャッシュメモリのサイズに依存しているため、効率を最大化するためにベンチマークを行う必要があります。
しかし、経験則として良い価値を選択するのを助けるために、次の2つのベンチマークを提供します。各グラフは、1〜10Kの異なるleaf_max_size値のツリービルド(水平)およびクエリ(垂直)時間を表します(95%の不確実性楕円形は、対数スケールのために変形しました)。
float座標があります):scan_071_points.dat freiburgキャンパス360データセットから、各ポイントには(x、y、z) float座標があります):したがって、 10〜50のleaf_max_size 、クエリのコストが支配するアプリケーションで最適になるようです(例:ICP)。現在、そのデフォルト値は10です。
KDTreeSingleIndexAdaptorParams::checksこのパラメーターはnanoflannでは本当に無視されていますが、元のFlannインターフェイスとの後方互換性のために保持されていました。それを無視するだけです。
KDTreeSingleIndexAdaptorParams::n_thread_buildこのパラメーターは、KDツリーの構築中に同時に呼び出すことができるスレッドの最大数を決定します。デフォルト値は1です。パラメーターが0に設定されている場合、 nanoflann使用するスレッドの数を自動的に決定します。
スレッドの最大数を使用することが常に最も効率的なアプローチではないことを示すいくつかのベンチマークのこのプルリクエストを参照してください。データをベンチマークしてください!
nanoflann :メモリの使用量が速く、より少ない「なぜフォークなのか」を参照してください。 nanoflann背後にある主な最適化のアイデアについては、上記のセクション。
nanoflannには明示的なSSE2/SSE3の最適化はありませんが、実際のinlineとテンプレートの集中的な使用は、コンパイラによって生成される自動的にSSE最適化コードに変換されます。
flann vs nanoflann多くのポイントクラウドアルゴリズム(ICPなど)の最も時間のかかる部分は、最近隣接するKDトリーをクエリすることです。したがって、この操作は最も重要な時間です。
nanoflann 、元のflann実装に関して約50%の時間節約を提供します(このチャートの時間は、クエリごとにマイクロ秒単位です):
ゲインのほとんどはクエリから来ていますが(ポイントクラウドを使用した典型的な操作の多くのため)、テンプレート化されたコードのためにKD-Treeインデックスを構築する際には、補助マトリックスのデータの複製を回避するための時間も保存されています(次のチャートの時間は、ミルシェントです)。
これらのパフォーマンステストは、私たちのテストのみを表しています。それらを繰り返したい場合は、パフォーマンスの指示を読んでください
注:プロジェクトのロゴは杉によるものです
貢献者