19

私は現在、OpenCV の ORB 機能エクストラクタを使用していますが、ORB 記述子が保存されている奇妙な (少なくとも私にとっては) 方法に気付きました (基本的に、私の質問に関係のない変更を加えた BRIEF-32 です)。ご存じの方もいらっしゃると思いますが、ORB は変更された FAST-9 (円の半径 = 9 ピクセル。キーポイントの方向も格納します) を使用して抽出されたキーポイントを取得し、変更された BRIEF-32 記述子を使用して、キーポイントが表す機能を格納します。

BRIEF (ORB バージョン) は次のように機能します。31x31 ピクセルのパッチ (フィーチャを表す) を取得し、ランダムな 5x5 ピクセルのテスト ポイントの束を作成します。次に、それらのポイントのペアを取得し、それらの強度を評価して、ペアの最初のポイントの強度が 2 番目のポイントの強度より大きいか小さいかに基づいてバイナリ決定 (0 または 1) を行います。次に、これらすべてのビットを取得し、基本的な合計式を使用して、長さ n のバイナリ文字列を作成します (BRIEFT-32 の場合、32 バイト * 8 = 256 ビット長のバイナリ文字列があります)。

SUM(2 (i-1) *bit_pair_test)

ここで、bit_pair_test は、テスト ポイントのペアのテストから計算したビット値です。最終結果は次のようになります (一連のバイナリ テスト (...,0,1,0,1,1) の場合):

(2 0 *1) + (2 1 *1) + (2 2 *0) + (2 3 *1) + (2 4 *0) + ...

OpenCV の ORB がこれらのビット文字列を格納する方法は、私にとって謎です。各行が 1 つのキーポイントの 1 つの記述子である画像全体の記述子を含むマトリックスを見ると、各記述子には 32 個の 8 ビットの数値が含まれていることがわかります。情報を保存します。256 ビットを 32 バイトに分割する理由がわかりません。公式ドキュメント ( http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_brief/py_brief.html ) は、OpenCV がそのような記述子をバイト単位で格納するとのみ述べていますが、なぜそれを行うのかについては説明していません。これらのいくつかの組み合わせが答えになる可能性を排除することなく、3 つの可能性を検討しました。

  • 見えない収納テクニック
  • その長さのバイナリ文字列 (この場合は 256 ビット) のハミング距離を計算する際のパフォーマンスの問題
  • マッチング プロセスの最適化 - マッチングは基本的に、1 つの画像のキーポイントの記述子を 2 番目の画像のキーポイントの記述子と比較します。バイナリ文字列があるため、ここではハミング距離が当然の選択です。どういうわけか、これらの 32 個の部分文字列のそれぞれが、2 番目の画像の他のキーポイントの記述子の対応する部分と比較される可能性があります (位置 0 の部分文字列 (キーポイント X、画像 1) と位置 0 の部分文字列 ( keypoint Y, image 2). 最後に、OpenCV は次のように言うかもしれません:「わかりました。すべての部分文字列の約 26 が両方の記述子で同じであるため、記述子の一致率は 80% であり、勝者がいます。」しかし、私はそれを確認する証拠を見つけることができませんでした.

PS: ORB に関する論文はこちらで、BRIEF に関する論文はこちらで読むことができます。

4

1 に答える 1

19

8 ビット パターンと 32 ビット パターンの選択は、ストレージと効率の問題によるものです。

  • マッチングの流れ

BRIEF、ORB、BRISK のビット順序は関係ありません (FREAK とは異なります)。したがって、これらの記述子のすべてのビットは同じ意味であり、ビットストリームの最初の部分などを比較することはできません。

一方、FREAK は、このようなマッチング プロセス ( FREAK の論文ではカスケードと呼ばれます) を念頭に置いて設計されました。

  • ストレージの問題

そうですね、コンピューターは個々のビットを保存しません。したがって、BRIEFT などをビット配列に格納する人はいません。

メモリから読み取ることができる最小のコンポーネントは 1 バイトです (通常は 8 ビットに相当しますが、一部の DSP は 16 ビットより小さいチャンクを読み取ることができませんが、それは別の話です)。したがって、記述子をバイト配列 (基になる OpenCV 実装言語である C/C++ の型) に格納する人々を見ることができます。unsigned char

さらに、変数がCPU のワード境界に整列している場合、通常はメモリ アクセスが向上 (高速) します。最近のほとんどの CPU には 32 ビットまたは 64 ビットのワードがあり、64 ビット アーキテクチャは従来の 32 ビット プロセッサを念頭に置いて設計されているため、32 ビット ワードの方が適しています。

  • 効率性の問題

ハミング距離は、XOR 演算によって計算されます。多くのプロセッサが、32 ビット ワード (64 ビット CPU がより一般的になる前の整数の一般的なサイズ) で XOR を効率的に計算できる専用の命令セットを持っていることがあります。さらに、 SIMD (Single Input Multiple Data) と呼ばれる並列処理技術である、複数の 32 ビット ワードで複数の XOR 値を並列に計算することもサポートする場合がありますたとえば、SSE 拡張機能を利用して、サイズが 32 ビットの倍数である BRIEF/ORB/... 記述子のハミング距離計算をさらに高速化できます。

于 2014-05-15T11:46:59.113 に答える