web-dev-qa-db-ja.com

2つのヒストグラムの比較

小さなプロジェクトの場合、ある画像を別の画像と比較する必要があります。画像がほぼ同じかどうかを判断するためです。画像は小さく、幅は25〜100ピクセルです。画像は同じ画像データであることが意図されていますが、微妙に異なるため、単純なピクセルの同等性チェックは機能しません。次の2つの可能なシナリオを検討してください。

  1. 展示を見ている博物館のセキュリティ(CCTV)カメラ:2つの異なるビデオフレームが同じシーンを表示するかどうかをすぐに確認したいが、照明とカメラフォーカスのわずかな違いは、それらが同一ではないことを意味します。
  2. 48x48でレンダリングされた同じアイコンと比較した64x64でレンダリングされたベクトルコンピューターGUIアイコンの画像(ただし、両方の画像は32x32に縮小されるため、ヒストグラムの合計ピクセル数は同じになります)。

ヒストグラムを使用して各画像を表すことにしました.3つの1Dヒストグラムを使用します:各RGBチャンネルに1つ-色を使用するだけで、テクスチャヒストグラムとエッジヒストグラムを無視しても安全です(別のアプローチでは、各画像に単一の3Dヒストグラムを使用し、しかし、それは余分な複雑さを追加するので、それを避けています。したがって、ヒストグラムを比較してそれらがどれほど似ているかを確認する必要があります。類似性の尺度がしきい値を超えた場合、各画像が視覚的に同じであると自信を持って言うことができます-各画像の対応するチャネルヒストグラムを比較します1の赤のヒストグラムと画像2の赤のヒストグラム、次に画像1の青のヒストグラムと画像2の青のヒストグラム、そして緑のヒストグラム-だから、私は画像1の赤のヒストグラムと画像2の青のヒストグラムを比較していません。

3つの画像の赤のRGBチャネルの要約を表すこれらの3つのヒストグラムがあるとしましょう(簡単にするために7ピクセルの画像に5つのビンを使用します)。

H1            H2            H3 

  X           X                     X
  X   X       X       X             X
X X   X X     X X   X X     X X X X X
0 1 2 3 4     0 1 2 3 4     0 1 2 3 4

H1 = [ 1, 3, 0, 2, 1 ]
H2 = [ 3, 1, 0, 1, 2 ]
H3 = [ 1, 1, 1, 1, 3 ] 

画像1(H1)は私の参照画像であり、画像2(H2)および/または画像3(H3)は画像1に似ています。この例では、画像2は画像1に似ていますが、画像3は似ていません。

「ヒストグラムの差」アルゴリズム(少なくとも私が理解できるアルゴリズム)の大まかな検索を行ったとき、各ビン間の差を単に合計することが一般的なアプローチであることがわかりましたが、このアプローチはすべてのビンの差が同じであるために失敗することがよくあります。

このアプローチの問題をデモンストレーションするには、C#コードで次のようにします。

Int32[] image1RedHistogram = new Int32[] { 1, 3, 0, 2, 1 };
Int32[] image2RedHistogram = new Int32[] { 3, 2, 0, 1, 2 };
Int32[] image3RedHistogram = new Int32[] { 1, 1, 1, 1, 3 };

Int32 GetDifference(Int32[] x, Int32[] y) {
    Int32 sumOfDifference = 0;
    for( int i = 0; i < x.Length; i++ ) {
        sumOfDifference += Math.Abs( x[i] - y[i] );
    }
    return sumOfDifferences;
}

出力は次のとおりです。

GetDifference( image1RedHistogram, image2RedHistogram ) == 6
GetDifference( image1RedHistogram, image3RedHistogram ) == 6

これは間違っています。

分布の形状を考慮した2つのヒストグラムの違いを判断する方法はありますか?

49
Dai

ヒストグラムを比較すること自体が非常に重要です。

比較関数には、ビン間比較とビン間比較という2つの大きなクラスがあります。

  • ビン対ビンの比較:既に述べたように、標準的な差の合計は非常に悪いです。 カイ2乗距離は改善されており、H1.red[0] = 0.001 and H2.red[0] = 0.011は、H1.red[0] = 0.1 and H2.red[0] = 0.11よりもはるかに重要であり、どちらの場合も|H1.red[0] - H2.red[0]| = 0.01です。
  • クロスビン比較:bin-similarity matrixと呼ばれる標準的な例では、M(i,j)がビンiとjの類似性である類似性マトリックスMが必要です。 bin[i]が赤であると仮定します。 bin[j]が暗赤色の場合、M(i,j)は大きくなります。 bin[j]が緑色の場合、M(i,j)は小さいです。この場合、ヒストグラムH1とH2の間の距離はsqrt((H1-H2)*M*(H1-H2))になります。この方法は、「近い」ビンについてあなたが言ったことを考慮に入れます! 地球移動距離(EMD)は、別の種類のクロスビン距離です。

最後に、3つのポイントがあります。

  • ヒストグラム距離に関するこのペーパー を読む必要があります。それは非常に簡単で、ヒストグラム距離を紹介します。私が話したすべての距離は、第1章でうまくまとめられています。正直なところ、この記事で説明されている最後のことはそれほど複雑ではありませんが、おそらくあなたの場合はやり過ぎです。
  • クロスビン距離は非常に優れていますが、コストがかかる可能性があります(つまり、マトリックスを含むため、計算に時間がかかり、O(n ^ 2)になります)。高価なクロスビン計算を回避する最も簡単な方法は(そして広く行われています)、ソフト割り当てを行うことです:ピクセルが赤の場合、リモートで赤のように見えるすべてのビンを埋める必要があります(もちろん、より多くの最も近い色への重み)。その後、ビン間アルゴリズムを使用できます。
  • もう少し数学中心:前のポイントは、クロスビン比較をビンツービン比較に減らすことでした。実際、それは暗黙的に類似性行列Mを対角化することから成ります。M = P'*D*Pを対角化できる場合、P'Pの転置で、その後sqrt((H1-H2)'*M*(H1-H2)) = sqrt((H1-H2)'*P'*D*P*(H1-H2)) = sqrt((P(H1-H2))'*D*(P(H1-H2)))です。 P(H1-H2)を計算するのがいかに簡単かによっては、計算時間を節約できます。直感的に、H1が元のヒストグラムである場合、P*H1はソフト割り当てであり、暗黙的な類似性マトリックスM = P'*Id*Pを使用しています
75
Fezvez

誰もヒストグラム比較のopencv実装について言及していないことに驚いています。また、異なる形式(uchar、float、doubleなど)のマルチチャネルイメージ(グレースケール、rgb、rgbaなど)を簡単に処理できます。

バタチャリャ距離、カイ二乗法、相関法、交差法が含まれます。あなたが見つけることができます

compareHist(InputArray H1, InputArray H2, int method)

マニュアルの機能 こちら

23
nkint

このタイプのヒストグラム比較には、Earth Mover's Distance(EMD)がよく使用されます。 EMDは、ヒストグラムのあるビンから別のビンにピクセルを「移動」するコストを定義する値を使用し、特定のヒストグラムをターゲットヒストグラムに変換する際の総コストを提供します。ビンが遠くなるほど、コストが高くなります。

あなたの例では、5単位をred [0]からred 1 に移動すると(c*1*5) 5ユニットを赤[0]から赤[10]に移動すると、コストが(c*10*5)

いくつかの実装があります。 FastEMD にはC++のコードがあり、JavaおよびMatlab。OpenCVにも何らかのサポートがあると思います。

大規模な画像データベースの類似検索のために、この手法を使用して公開された多くの論文があります。

14
tkerwin

ヒストグラムを比較する場合、カイ二乗検定を開始するのに適した場所であることがわかりました。各ヒストグラムに同じ数のエントリがない場合は、「通常の」式を使用できないため、もう少し注意する必要があります。メモリから、ヒストグラムのエントリ数が等しくないと仮定すると、カイ二乗検定は一般化されます

1 /(MN)SUM_i [((Mni-Nmi)^ 2)/(mi + ni)]。

MとNは各ヒストグラムのエントリの総数、miはヒストグラムMのビンiのエントリの数、niはヒストグラムNのビンiのエントリの数です。

もう1つのテストは、コルモゴロフ-スミルノフテストです。このテストでは、2つのヒストグラムの累積確率分布の最大差を調べます。これを実装するのは難しいです。Cの数値レシピにはCのコードスニペットがあり、Matlabにあると確信しています。違いにもっと興味がある場合はヒストグラムの形状であり、正確な値はそれほど多くないので、これはそのノンパラメトリックでもより良いテストになるでしょう。

6
Bowler

基本的には、 確率距離 を探します。多数あり、アプリケーションに適したものを決定する必要があります。最近、私はカイ二乗とカルバック・ライブラーで運が良かった。

4
Chris A.

着信ヒストグラムの各ビンの値を、ヒストグラムのベースとなるピクセルの総数で除算することにより、ヒストグラムを正規化します。次に、 @ tkerwinのEMD を使用します。

2
jilles de wit

EMDはビン間方法と比較してクロスビン問題を解決するための良い解決策だと思います。ただし、いくつか言及するように、EMDは非常に長い時間です。クロスビンのためのいくつかの他のアプローチを私に提案してもらえますか?

0
John

他の人が言及したように、Earth Mover's DistanceまたはEMD(別名Wassersteinメトリック)はおそらく最適なソリューションです。高速EMD計算のショートリストメソッドは、Rパッケージ transport で利用できます。 2014年の論文 で紹介され、他の方法と比較して、計算時間が短縮されました。唯一の欠点は、R内にあることです。これは、ボンネットの下でC++でプログラムしない限り高速ではありません。

0
Adam Erickson