多くの画像の類似性を比較するための画像指紋


94

すべての画像を他のすべての画像と非常に高速に比較するには、多くの画像(既存の約100.000、1日あたり新しい1000、RGB、JPEG、最大サイズ800x800)のフィンガープリントを作成する必要があります。ほぼ同じような画像も認識される必要があるため、バイナリ比較メソッドを使用できません。

最善の方法は既存のライブラリですが、既存のアルゴリズムへのヒントも私に役立ちます。


1
ライブラリが使用する言語は?
ベンS

回答:


57

通常のハッシュまたはCRC計算アルゴリズムは、画像データではうまく機能しません。情報の次元的な性質を考慮する必要があります。

アフィン変換(スケーリング、回転、変換、フリッピング)を考慮に入れるなど、非常に堅牢なフィンガープリントが必要な場合は、画像ソースでラドン変換を使用して、画像データの規範的なマッピングを作成できます-これを各画像と一緒に保存し、次に、指紋のみを比較します。これは複雑なアルゴリズムであり、気弱な人には向いていません。

いくつかの簡単な解決策が可能です:

  1. 画像の明度ヒストグラムを指紋として作成する
  2. 各画像の縮小版を指紋として作成する
  3. 手法(1)と(2)をハイブリッドアプローチに組み合わせて、比較品質を向上させる

明度ヒストグラム(特にRGBコンポーネントに分離されたもの)は、画像の妥当なフィンガープリントであり、非常に効率的に実装できます。1つのヒストグラムを別のヒストグラムから差し引くと、新しいヒストグラムが生成されます。これを処理して、2つの画像がどの程度類似しているかを判断できます。ヒストグラムは、明度/色情報の分布と発生を評価するだけなので、アフィン変換が非常にうまく処理されます。各カラーコンポーネントの明度情報を8ビット値に量子化する場合、ほとんどすべての妥当なサイズのイメージのフィンガープリントには、768バイトのストレージで十分です。画像の色情報が操作されると、輝度ヒストグラムは偽陰性を生成します。コントラスト/明るさ、ポスタリゼーション、カラーシフトなどの変換を適用すると、輝度情報が変化します。

スケーリングされた画像を使用することは、画像の情報密度を比較しやすいレベルに下げる別の方法です。元の画像サイズの10%未満に縮小すると、通常、使用する情報が多すぎて失われるため、800x800ピクセルの画像を80x80に縮小しても、適切なフィンガープリントを実行するのに十分な情報を提供できます。ヒストグラムデータとは異なり、ソース解像度のアスペクト比が異なる場合は、画像データの異方性スケーリングを実行する必要があります。つまり、300x800の画像を80x80のサムネイルに縮小すると、画像が変形し、300x500の画像(非常によく似ている)と比較すると、偽陰性が発生します。サムネイルフィンガープリントは、アフィン変換が関係する場合に、しばしば偽陰性を生成します。画像を反転または回転させると、

両方の手法を組み合わせることは、賭けをヘッジし、偽陽性と偽陰性の両方の発生を減らすための合理的な方法です。


CRCに関しては、同意した。ただし、使用したい場合は、CRC32よりもMD5ハッシュを使用するほうがよい
mloskot

5
MD5は一方向の暗号ハッシュであるため、MD5を使用する必要はありません。ハッシュ間の違いを直接比較できるように、同様の入力に対して同様の結果を生成するハッシュ方式を使用する必要があります。
AJ Quick

34

ここで提案されている一般的なフレーバーを保持する縮小された画像バリアントよりもアドホックなアプローチははるかに少ないですが、何が起こっているかについてより厳密な数学的基礎を提供します。

テイクハールウェーブレット画像のを。基本的に、Haarウェーブレットは、低解像度の画像から高解像度の各画像への一連の違いですが、ミップマップの「ツリー」内の深さによって重み付けされます。計算は簡単です。次に、Haarウェーブレットに適切な重みを付けたら、k個の最大係数(絶対値に関して)を除いてすべて破棄し、ベクトルを正規化して保存します。

これらの正規化されたベクトルのうち2つのドット積をとると、1がほぼ同一であるという類似性の尺度が得られます。詳細情報を投稿しましたこちらました


20

あなたは間違いなくphashを見てみるべきです

画像比較のために、このphpプロジェクトがありますhttps : //github.com/kennethrapp/phasher

そして私の小さなjavascriptクローン:https : //redaktor.me/phasher/demo_js/index.html

残念ながら、これは「ビットカウント」ベースですが、回転した画像を認識します。JavaScriptのもう1つのアプローチは、キャ​​ンバスを使用して画像から輝度ヒストグラムを作成することでした。キャンバス上のポリゴンヒストグラムを視覚化し、データベース内のそのポリゴンを比較できます(例:mySQL空間...)


これはnpmですか?私は、javascriptを使用して2つの画像の類似性を比較する方法を探しています
Chovy

うーん、「npmで安い」と思った。それは本当にゼロから素早く書かれた単なるデモでした。ただし、ソースについては何でも好きなようにしてください。作成できる場合は後で調べて、github github.com/redaktorにプッシュします...
sebilasse

@SebastianLasse私はあなたのJSポートをチェックアウトしました、そしてそれは素晴らしいです!Compare()最初に画像をダウンロードする代わりに、画像のURIを関数に渡してほしいと思います。また、私のテストでは、「非常に類似した画像」のしきい値は> 98%ではなく> 90%である必要があります。
thdoan

12

昔、私はいくつかの類似した特性を持つシステムに取り組みました、そしてこれは私たちが従ったアルゴリズムの近似です:

  1. 画像をゾーンに分割します。私たちのケースでは4:3解像度のビデオを扱っていたため、12ゾーンを使用しました。これを行うと、画像からソース画像の解像度が失われます。
  2. 各ゾーンについて、全体的な色-ゾーン内のすべてのピクセルの平均を計算します
  3. 画像全体について、全体的な色-すべてのゾーンの平均を計算します

したがって、各画像n + 1について、整数値を格納します。nで、は追跡しているゾーンの数です。

比較のために、各カラーチャネルを個別に確認する必要もあります。

  1. 全体的な画像について、全体的な色のカラーチャネルを比較して、それらが特定のしきい値(たとえば10%)内にあるかどうかを確認します。
  2. 画像がしきい値内にある場合は、次に各ゾーンを比較します。すべてのゾーンもしきい値内にある場合、画像は十分に一致しているため、さらに比較するためにフラグを立てることができます。

これにより、一致しない画像をすばやく破棄できます。より多くのゾーンを使用したり、アルゴリズムを再帰的に適用したりして、一致の信頼性を高めることもできます。


6

Icの回答に似ています。複数の解像度で画像を比較してみてください。したがって、各画像は1x1、2x2、4x4 .. 800x800として保存されます。最低解像度が一致しない場合(しきい値がある場合)、すぐに拒否できます。一致する場合は、次に高い解像度で比較できます。

また、画像が医用画像などの類似の構造を共有している場合は、その構造を比較しやすい/速い説明に抽出できる場合があります。


これは、ある種の木の検索に対応しています。それは面白い。
アンドレ・ラズロ

3

したがって、「画像照合」とはかなり異なる「指紋照合」を実行したいとします。指紋の分析は過去20年間に深く研究されており、適切な検出率を保証するためにいくつかの興味深いアルゴリズムが開発されています(FARおよびFRR指標- 誤認率および誤認率)。)。

LFA(Local Feature Analysis)クラスの検出手法をよりよく調べることをお勧めします。主に特徴点の検査に基づいて構築されています。特徴点は指紋の特定の特性であり、いくつかのクラスに分類されています。ラスターイメージをマニューシャマップにマップすることは、実際にはほとんどの公的機関が犯罪者やテロリストを提出するために行うことです。

詳細はこちらをご覧ください


特定の生体認証システムのスコアのガウス分布がある場合に、偽受容率を計算する方法を知っていますか?
GobiasKoffi

OPは「多くの画像のフィンガープリントを作成」したいと考えています。人間の指紋の画像を比較しません。
Navin


3

2015年現在(将来に戻る...現在Googleで上位にランク付けされている2009年の質問について)、画像の類似性はディープラーニング技術を使用して計算できます。自動エンコーダーと呼ばれるアルゴリズムのファミリーは、類似性を検索可能なベクトル表現を作成できます。ここにデモがあります


バイナリデータから指紋画像を生成することは可能ですか?
SwR 2016年

確かに、このタスクにはANNがありますが、あなたの答えは実際には何も答えていないようです。質問です:それはどのように行われますか?リンク先のページには情報が開示されておらず、「オートエンコーダー」という用語も役に立ちません。
Simon Steinberger

元の質問には「どうやってやるの?」とは書かれていませんが、「既存のアルゴリズムに対するヒントが私を大いに助けてくれる」と書いてあります。
Alex R

「ヒント」をアルゴリズムにリンクしていませんでした。実際、リンクされたページには「それは機能しますが、理由はわかりません。結果についてあまり期待しないでください」...
odyth

このdeeplearning4j.org/deepautoencoder#use-casesは、自動エンコーダーを使用して指紋を作成する方法と、その指紋を使用して頂点の類似度に基づいて他の画像の類似点を見つける方法をより明確にします。
オディス

2

これを行う方法の1つは、画像のサイズを変更して解像度を大幅に(おそらく200x200に?)下げ、比較を行うための小さい(ピクセル平均)バージョンを保存することです。次に、許容しきい値を定義し、各ピクセルを比較します。すべてのピクセルのRGBが許容範囲内にある場合は、一致しています。

最初の実行はO(n ^ 2)ですが、すべての一致をカタログ化すると、新しい画像はそれぞれ比較するO(n)アルゴリズムになります(以前に挿入した各画像と比較するだけで済みます)。しかし、比較する画像のリストが大きくなるにつれて、最終的には機能しなくなりますが、しばらくの間は安全だと思います。

400日間実行すると、500,000の画像が得られます。つまり、(画像のサイズを変更する時間を割り引く)200(H)*200(W)*500,000(images)*3(RGB)= 60,000,000,000の比較になります。すべての画像が完全に一致している場合、遅れることになりますが、そうではないでしょうか?単一の比較がしきい値を超えるとすぐに、画像を一致として割引できることを覚えておいてください。


2

文字通りすべての画像を他の画像と比較したいですか?アプリケーションとは何ですか?たぶん、特定の記述子に基づいて画像の何らかのインデックス付けと検索が必要なだけですか?次に、たとえば、マルチメディアコンテンツ記述インターフェイスのMPEG-7標準を確認できます。次に、さまざまな画像記述子を比較できますが、これはそれほど正確ではありませんが、はるかに高速です。


たぶん徹底的か限定的かの選択かもしれない
ジョニー

0

特殊な画像ハッシュアルゴリズムは活発に研究されている領域のようですが、おそらく画像バイトの通常のハッシュ計算でうまくいくでしょう。

同じソースから派生したが、形式や解像度が異なる可能性がある画像を探すのではなく、バイトが同一の画像を探していますか(かなり難しい問題として私を襲います)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.