web-dev-qa-db-ja.com

OpenCV / SURF記述子から画像ハッシュ/フィンガープリント/署名を生成する方法は?

同様の画像を見つける方法について非常に役立ついくつかのトピックがここにあります。

私がやりたいのは、写真の指紋を取得し、デジタルカメラで撮影した別の写真で同じ写真を見つけることです。 SURFアルゴリズムは、スケーリング、角度、その他の歪みに依存しない最善の方法になるように継ぎ合わせます。

OpenCVとSURFアルゴリズムを使用して、サンプル画像の特徴を抽出しています。今、私はこのすべての特徴データ(位置、ラプラシアン、サイズ、方向、ヘッセ行列)を指紋またはハッシュに変換する方法を考えています。

このフィンガープリントはデータベースに保存され、検索クエリはそのフィンガープリントをほぼ同じ機能を持つ写真のフィンガープリントと比較できる必要があります。

更新:

すべての記述子ベクトルを単純なハッシュに変換する方法はないようです。では、高速なクエリのために画像記述子をデータベースに保存する最良の方法は何でしょうか?

語彙ツリーはオプションでしょうか?

どんな助けにも感謝します。

37
dan

あなたが言及した特徴データ(位置、ラプラシアン、サイズ、方向、ヘッセ行列)は、目的には不十分です(これらは、マッチングを行う場合、実際には記述子の関連性の低い部分です)。調べたいデータは「記述子」(4番目の引数)です。

void cvExtractSURF(const CvArr * image、const CvArr * mask、CvSeq ** keypoints、CvSeq ** descriptors、CvMemStorage * storage、CvSURFParams params)

これらは128または64(paramsに依存)のベクトルであり、特定の機能の「フィンガープリント」が含まれています(各画像にはさまざまな量のそのようなベクトルが含まれます)。 Opencvの最新バージョンを入手した場合、それらはfind_obj.cppという名前のサンプルを持っています。

更新

this ディスカッションが役立つかもしれません

9
elijah

ハッシュを計算する簡単な方法は次のようになります。画像からすべての記述子を取得します(たとえば、N個)。各記述子は、128個の数値のベクトルです(0〜255の整数に変換できます)。したがって、N * 128整数のセットがあります。それらを次々に文字列に書き込み、それをハッシュ値として使用するだけです。ハッシュ値を小さくしたい場合は、文字列のハッシュ関数を計算する方法があると思います。そのため、記述子を文字列に変換してから、その文字列のハッシュ値を使用します。

正確な重複を見つけたい場合は、うまくいくかもしれません。しかし、(スケール、回転などについて話しているので) "類似した"画像を見つけたいだけのようです。その場合、ハッシュを使用することはおそらく良い方法ではありません。おそらく、関心点検出器を使用して、SURF記述子を計算するポイントを見つけます。同じポイントのセットが異なる順序で返されることを想像してください。画像と記述子が同じであっても、ハッシュ値は突然大きく異なります。

したがって、類似した画像を確実に見つける必要がある場合は、別の方法を使用します。たとえば、SURF記述子をベクトル量子化し、ベクトル量子化値のヒストグラムを作成し、マッチングにヒストグラムの交差を使用できます。あなたは本当に(おそらく効率のために)ハッシュ関数を使用する必要がありますか、それとも類似の画像を見つけるために何でも使用したいですか?

3
user245973

Min-Hashまたはmin-Hashingは、役立つ技術です。画像全体を調整可能なサイズの表現でエンコードし、ハッシュテーブルに格納します。 Geometric min-HashingPartition min-HashおよびBundle min-Hashing存在します。結果のメモリフットプリントは最小の1つではありませんが、これらの手法は、ほぼ重複した検索や小さなオブジェクトの検索など、さまざまなシナリオで機能します。

このトピックにはいくつかの論文があります。エントリー文献は次のようになります:ほぼ重複する画像の検出:min-Hashおよびtf-idfの重み付けOndrej Chum、James Philbin、Andrew Zisserman、BMVC 2008[〜#〜] pdf [〜#〜]

2
Stefan

Gistを使用する方が適切かもしれません。

http://people.csail.mit.edu/torralba/code/spatialenvelope/ にはMATLABコードがあります。

2
forefinger