私は現在、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% であり、勝者がいます。」しかし、私はそれを確認する証拠を見つけることができませんでした.