38

私は問題があります。私の会社は私にひどく退屈な仕事を与えてくれました。ダイアログボックスのデータベースが2つあります。これらのデータベースの1つには、恐ろしい品質の画像が含まれ、もう1つには非常に高品質の画像が含まれています。

残念ながら、恐ろしい品質のダイアログには、他の情報への重要なマッピングが含まれています。

私は手動で、すべての悪い画像を調べて、それらを良い画像に一致させるという任務を負っています。

このプロセスをある程度自動化することは可能でしょうか?これは2つのダイアログボックスの例です(Google画像からランダムに抽出されます):

良質の画像

質の悪い画像

そのため、現在、C#でプログラムを作成して、データベースからこれらの写真を取得し、それらを循環させ、一般的な形状の写真を見つけて、それらのIDを返すようにしています。ここでの私の最良の選択肢は何ですか?

4

18 に答える 18

28

これに外部ライブラリを使用する理由はまったくありません。この種のことを何度も行ってきましたが、次のアルゴリズムは非常にうまく機能します。2 つの画像を比較する場合、サイズは同じですが、そうでない場合はサイズを変更できます。

badness := 0.0
For x, y over the entire image:
  r, g, b := color at x,y in image 1
  R, G, B := color at x,y in image 2
  badness += (r-R)*(r-R) + (g-G)*(g-G) + (b-B)*(b-B)
badness /= (image width) * (image height)

これで、2 つの画像間の正規化された悪い値が得られました。悪い値が低いほど、画像が一致する可能性が高くなります。これはシンプルで効果的です。特定のケースでより良くまたはより速く動作するようにするさまざまなものがありますが、おそらくそのようなものは必要ありません。悪さを正規化する必要さえありませんが、手動でいくつかの可能な一致を調べたい場合は、この方法で単一のしきい値を考え出すことができます。


この質問が注目を集めたので、多くの画像を何度も処理する場合にこれを高速化する方法を追加することにしました。数万の画像を比較する必要があり、典型的な画像のペアが大きく異なることがわかっていたときに、このアプローチを使用しました。また、すべての画像がまったく同じ寸法になることもわかっていました。ダイアログボックスを比較している状況では、典型的な画像はほとんど灰色がかっており、一部の画像のサイズを変更する必要がある場合があります (ただし、それは単に不一致を示しているだけかもしれません)。多くの。

アイデアは、各ノードがノードが表す領域の平均 RGB 値を表す四分木を形成することです。したがって、4x4 画像には、画像の平均 RGB 値に等しい RGB 値を持つルート ノードがあり、その子にはそれぞれの 2x2 領域の平均 RGB 値を表す RGB 値があり、その子は個々のピクセルを表します。(実際には、約 16x16 の領域よりも深くならないことをお勧めします。その時点で、個々のピクセルの比較を開始する必要があります。)

画像の比較を開始する前に、悪いしきい値も決定する必要があります。信頼できる精度でこのしきい値を超える悪さを計算することはないため、これは基本的に、画像に「一致しない」というラベルを付けるしきい値です。

画像 A と画像 B を比較するときは、最初に四分木表現のルート ノードを比較します。単一ピクセル画像の場合と同じように悪さを計算し、悪さがしきい値を超えた場合はすぐに戻り、このレベルでの悪さを報告します。正規化された悪さを使用しており、悪さは差の 2 乗を使用して計算されるため、特定のレベルでの悪さは、より低いレベルでの悪さと同じかそれ以下になります。個々のピクセルのレベルでのしきい値。

nxn 画像でしきい値テストに合格した場合は、次のレベルに落として、2nx2n 画像のように比較します。十分に低くなったら、個々のピクセルを比較します。画像のコーパスによっては、これにより多くの比較をスキップできる場合があります。

于 2012-07-26T15:34:24.627 に答える
15

個人的には、画像ハッシュ アルゴリズムを使用します。

画像ハッシュの目的は、圧縮された表現を取得するために、画像コンテンツを特徴シーケンスに変換することです。この特徴シーケンス (つまり、ビットのベクトル) は、高速マッチングのために十分に短く、類似性測定を実現するために識別可能な特徴を維持する必要があります。

オープン ソース コミュニティを通じて自由に利用できるアルゴリズムがいくつかあります。

簡単な例は、この記事で見つけることができます。Neal Krawetz 博士は、平均ハッシュ アルゴリズムがどのように機能するかを示しています。

  1. サイズを縮小します。高周波とディテールを除去する最も速い方法は、画像を縮小することです。この場合、合計 64 ピクセルになるように 8x8 に縮小します。アスペクト比を維持する必要はありません。8x8 の正方形に収まるように縮小してください。このようにして、スケールや縦横比に関係なく、ハッシュは画像のあらゆるバリエーションと一致します。
  2. 色を減らします。小さな 8x8 画像がグレースケールに変換されます。これにより、ハッシュが 64 ピクセル (赤 64、緑 64、青 64) から合計 64 色に変更されます。
  3. 色を平均化します。64 色の平均値を計算します。
  4. ビットを計算します。これは楽しい部分です。各ビットは、色の値が平均より上か下かに基づいて設定されます。
  5. ハッシュを構築します。64 ビットを 64 ビット整数に設定します。一貫性がある限り、順序は重要ではありません。(ビッグエンディアンを使用して、ビットを左から右、上から下に設定します。)

David Oftedalは、Average Hash アルゴリズムを使用して画像を分類および比較できるC# コマンドライン アプリケーションを作成しました。(サンプル画像で彼の実装をテストしたところ、98.4% の類似性が得られました)。

このソリューションの主な利点は、各画像を 1 回だけ読み取り、ハッシュを作成して、類似性に基づいて (たとえば、ハミング距離を使用して) 分類することです。

このようにして、特徴抽出フェーズを分類フェーズから分離し、十分に正確でないことがわかった場合は、別のハッシュ アルゴリズムに簡単に切り替えることができます。


編集

ここで簡単な例を見つけることができます(40 枚の画像のテスト セットが含まれており、40/40 のスコアが得られます)。

于 2012-07-31T20:25:49.850 に答える
6

商用TinEyeAPIは本当に良いオプションです。

私は過去に画像マッチングプログラムを行ってきましたが、最近の画像処理技術は驚くべきものであり、その進歩は非常に進んでいます。

psここにあなたがグーグルから引っ張ったそれらの2つのランダムな写真が来たところです: http ://www.tineye.com/search/1ec9ebbf1b5b3b81cb52a7e8dbf42cb63126b4ea/

于 2012-07-31T05:50:33.223 に答える
6

これは、 OpenCVライブラリに既に実装されているアルゴリズムとの画像の類似性について議論するトピックです。低レベル関数を C# アプリケーションにインポートするのに問題はないはずです。

于 2012-07-26T14:13:45.117 に答える
5

これは 1 回限りの作業なので、スクリプト (好きな言語を選択してください。おそらく Perl を選びます) とImageMagick. C# を使用してスクリプトと同じことを実行できますが、より多くのコードが必要になります。コマンド ライン ユーティリティを呼び出して、結果の出力を解析するだけです。

ペアの類似性をチェックするスクリプトは、次のように約 10 行になります。

最初にサイズを取得し、identify縦横比がほぼ同じであることを確認します。そうでない場合は、一致しません。その場合は、大きい方の画像を で小さい方のサイズに合わせconvertます。事前にオプションを少し試してfilter、既知の同等の画像で最も類似性が高いものを見つける必要があります。それらのうちの9つが利用可能です。

次に、compare関数を使用して類似度メトリックを生成します。Compare は、変換とトリミングを処理するのに十分スマートです。試行錯誤して、誤検知があまり発生しない類似性のしきい値を見つけてください。

于 2012-07-30T20:51:13.603 に答える
2

特定のバッチマッチングの問題を解決するには、これに対するハイブリッドアプローチが最適だと思います

  1. @Paolo Morreti によって提案された画像ハッシュ アルゴリズムをすべての画像に適用します。
  2. 1 つのセット内の各画像について、設定された距離に近いハッシュを持つ画像のサブセットを見つけます
  3. この縮小された検索スペースに対して、@Running Wild または @Raskolnikov によって提案されている高価なマッチング方法を適用できるようになりました...最良の方法が勝ちます。
于 2012-08-02T11:27:16.967 に答える
2

私はこのようなことをします:

  • ぼやけた画像がどのようにぼやけているかが既にわかっている場合は、同じ関数を高品質の画像に適用してから比較します。

    • 次に、上記のように最小二乗法を使用して画像を比較します。
    • 最低値が一致するはずです。理想的には、両方の画像が同一の場合は 0 になります
    • 物事をスピードアップするために、ダウンサンプリングされた画像でほとんどの比較を実行してから、選択した画像のサブサンプルを絞り込むことができます
  • わからない場合は、さまざまな可能性のある機能 (JPEG 圧縮、ダウンサンプリングなど) を試して、繰り返します。

于 2012-07-31T11:44:16.610 に答える
2

Content-Based Image Retrieval ( CBIR ) を試すことができます。

率直に言えば:

  1. データベース内のすべての画像について、フーリエ変換を使用してフィンガープリントを生成します
  2. ソース画像を読み込み、画像のフィンガープリントを作成します
  3. ソースとデータベース内のすべての画像の間のユークリッド距離を計算します
  4. 結果を並べ替える
于 2012-08-02T05:04:08.077 に答える
1

画像のピクセル差だけを計算する場合、同じサイズの画像、または水平方向と垂直方向に拡大縮小する方法を正確に知っている場合にのみ機能します。また、シフトや回転の不変性はありません。

したがって、最も単純な形式の問題がある場合にのみピクセル差メトリックを使用することをお勧めします(画像はすべての特性で同じですが、品質が異なります。ちなみに、品質が異なるのはなぜですか?jpegアーティファクトまたは単に再スケーリングしますか?)、そうでない場合は、正規化された相互相関を使用すると、より安定したメトリックになります。あなたはFFTWまたはOpenCVでそれを行うことができます。

于 2012-07-31T08:35:54.610 に答える
1

画像から輪郭を抽出すると、ShapeContextを使用して画像の非常に優れたマッチングを得ることができます。

ShapeContextは、この正確なもののために構築されています(相互の形状に基づいて画像を比較します)

ShapeContext実装リンク: 元の出版物 ShapeContextに関する主題の CodeProjectページのgoot ppt

*しきい値やフーリエ変換などのいくつかの「輪郭抽出」手法を試す必要がある場合があります。または、輪郭抽出についてこのCodeProjectページを参照してください。

幸運を。

于 2012-07-30T06:33:37.337 に答える
1

解像度が低いことが原因で品質が悪い場合は、次のようにします。

  • 高品質の画像を低品質の画像解像度に再スケーリングします(または両方を低解像度に再スケーリングします)
  • 各ピクセルの色を比較して、最も近い一致を見つけます

したがって、たとえば、すべての画像を 32x32 に再スケーリングし、そのセットをピクセル単位で比較すると、非常に合理的な結果が得られますが、それでも簡単に行うことができます。ここでは再スケーリング方法が違いを生む可能性がありますが。

于 2012-08-01T15:47:37.110 に答える
1

私見、最良の解決策は、両方の画像をぼかし、後でいくつかの類似度(相関/相互情報など)を使用して上位K(K = 5の可能性がありますか?)の選択肢を取得することです。

于 2012-07-26T14:09:10.433 に答える
0

Running Wild の答えは非常に近いものです。ここで行っているのは、各画像のピーク信号対雑音比 (PSNR) を計算することです。あなたの場合、本当に必要なのは平均二乗誤差だけですが、その二乗成分は画像間の差を計算するのに大いに役立ちます。

PSNR リファレンス

コードは次のようになります。

sum = 0.0
for(imageHeight){
  for(imageWidth){
    errorR = firstImage(r,x,y) - secondImage(r,x,y)
    errorG = firstImage(g,x,y) - secondImage(g,x,y)
    errorB = firstImage(b,x,y) - secondImage(b,x,y)
    totalError = square(errorR) + square(errorG) + square(errorB)
  }
  sum += totalError
}
meanSquaredError = (sum / (imageHeight * imageWidth)) / 3
于 2012-07-31T00:23:53.673 に答える
0

2 つのデータベースの画像には同じダイアログが表示され、画像はほぼ同一であるが品質が異なるはずだと思いますか? 次に、一致する画像の縦横比は同じ(または同じに非常に近い)になります。

低品質画像が高品質画像 (または同等の画像) から生成された場合、高品質画像の前処理ステップと同じ画像処理手順を使用し、低品質画像データベースと照合する必要があります。次に、ピクセルごとの比較またはヒストグラム マッチングがうまく機能するはずです。

画像が多数ある場合、画像マッチングは多くのリソースを使用する可能性があります。多分マルチパスアプローチは良い考えですか?例: パス 1: 画像をグループ化するために縦横比のような単純な尺度を使用します (幅と高さのフィールドは db?) (計算的に安価です) パス 2: 1 番目のカラー チャネル (またはすべてのチャネル) のヒストグラムによって一致またはグループ化します (比較的計算的に安いです)

OpenCVもお勧めします。これは、c、c++、および Python (および間もなく Java) で使用できます。

于 2012-07-31T11:28:31.343 に答える
0

歩行平均ウィンドウ (RGB 値の場合) と組み合わせて、輪郭/しきい値の手法を試しましたか?

于 2012-08-02T14:34:09.247 に答える
0

私は Running Wild のアルゴリズムがとても気に入っています。例えば、より良い方の品質を下げるなどして、2 つの画像をより似たものにできれば、さらに効果的だと思います。

于 2012-07-30T06:45:09.653 に答える
0

大声で考えているだけです:

レイヤーとして比較する必要がある 2 つの画像を使用し、これらを組み合わせる (一方を他方から減算する) と、新しい画像が得られます (一部の描画プログラムはバッチ変換を行うようにスクリプト化できます。または、小さな DirectX またはOpenGL プログラム)

次に、結果の画像の明るさを取得する必要があります。暗いほど、一致度が高くなります。

于 2012-08-01T08:46:23.337 に答える
0

特定の問題に対する正確な有効性はわかりませんが、ブロックマッチングアルゴリズムを試すことができます - http://scien.stanford.edu/pages/labsite/2001/ee368/projects2001/dropbox/project17/block.html - http://www.aforgenet.com/framework/docs/html/05d0ab7d-a1ae-7ea5-9f7b-a966c7824669.htm

これが機能しない場合でも、Aforge.net ライブラリを確認する必要があります。このプロセスに役立ついくつかのツールがあります (上記のブロック マッチングを含む) - http://www.aforgenet.com/

于 2012-07-26T14:14:26.903 に答える