重複する画像を見つけるためのツールをC#で書いています。現在、ファイルのMD5チェックサムを作成し、それらを比較します。
残念ながら私の画像は
この問題を解決するための最良のアプローチは何でしょうか?
256ビットのイメージハッシュ(MD5は128ビット)を使用した簡単なアプローチを次に示します。
List<bool>
に読み込みます-これはハッシュですコード:
public static List<bool> GetHash(Bitmap bmpSource)
{
List<bool> lResult = new List<bool>();
//create new image with 16x16 pixel
Bitmap bmpMin = new Bitmap(bmpSource, new Size(16, 16));
for (int j = 0; j < bmpMin.Height; j++)
{
for (int i = 0; i < bmpMin.Width; i++)
{
//reduce colors to true / false
lResult.Add(bmpMin.GetPixel(i, j).GetBrightness() < 0.5f);
}
}
return lResult;
}
GetPixel
はそれほど高速ではありませんが、16x16ピクセルの画像ではボトルネックにならないはずです。
コード:
List<bool> iHash1 = GetHash(new Bitmap(@"C:\mykoala1.jpg"));
List<bool> iHash2 = GetHash(new Bitmap(@"C:\mykoala2.jpg"));
//determine the number of equal pixel (x of 256)
int equalElements = iHash1.Zip(iHash2, (i, j) => i == j).Count(eq => eq);
したがって、このコードは次のもので等しい画像を見つけることができます:
i
およびj
の反復順序を変更することにより更新/改善:
この方法をしばらく使用した後、いくつかの改善点に気づいた
GetPixel
はパフォーマンスを向上させます0.5f
を明暗で異なる値に設定する代わりに、256ピクセルすべての明度の中央値を使用します。それ以外の場合、暗い/明るい画像は同じであると想定され、明るさが変化した画像を検出することができます。bool[]
またはList<bool>
を使用します。メモリを節約する必要がある多くのハッシュを保存する必要がある場合は、Bitarray
を使用します。少し格納されません、 byte !2つの画像を比較するアルゴリズム をチェックして、画像比較に利用可能な方法を確認できます。
完全なアルゴリズムを自分で再作成する場合を除き、既存のライブラリまたはそのコードの最小限の部分を使用してみてください(ライセンスが問題ない限り)。
エッジ検出および関連するコンピュータービジョンアルゴリズムのオープンソースC#実装の場合、OpenCVのラッパーである EmguCV を試すことができます。
画像を一般的な解像度にリサンプリングした後、ウェーブレット分解を使用して、画像自体の代わりにこの分解の係数を比較できます。最初のN個の係数のみを比較すると、この方法はノイズやその他のアーティファクトに対してより堅牢になります。
利用可能なウェーブレットのC#実装がいくつかあります。たとえば、 https://waveletstudio.codeplex.com/
興味深い質問ですが、画像の比較はそれほど難しくありませんが、
比較を行う1つの方法は、
ここで、値が90%などの妥当な値の範囲内にある場合(おそらく、いくつかの実験を行って決定する必要があります)、両方が同じであると安全に想定できますが、