from - imagehashing c#




Algorithmus zum Vergleichen von zwei Bildern in C# (3)

Hier ist ein einfacher Ansatz mit einem 256-Bit-Image-Hash (MD5 hat 128 Bit)

  1. Ändern Sie die Bildgröße auf 16x16 Pixel

  1. Farben auf Schwarz / Weiß reduzieren (was in dieser Konsolenausgabe true / false entspricht)

  1. Lesen Sie die booleschen Werte in List<bool> - dies ist der Hash

Code :

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;
}

Ich weiß, GetPixel ist nicht so schnell, aber auf einem 16x16 Pixel-Bild sollte es nicht der Engpass sein.

  1. Vergleichen Sie diesen Hash mit Hash-Werten aus anderen Bildern und fügen Sie eine Toleranz hinzu (Anzahl der Pixel, die vom anderen Hash abweichen können).

Code:

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);

Dieser Code kann also gleiche Bilder finden mit:

  • verschiedene Dateiformate (zB jpg, png, bmp)
  • Drehung (90, 180, 270), horizontale / vertikale Umkehrung - durch Ändern der Iterationsreihenfolge von i und j
  • unterschiedliche Abmessungen (gleicher Aspekt ist erforderlich)
  • Unterschiedliche Komprimierung (Toleranz bei Qualitätsverlust wie JPEG-Artefakten erforderlich) - Sie können akzeptieren, dass 99% dasselbe Bild und 50% ein anderes Bild sind.
  • farblich geändert in geyskaliert und umgekehrt (da die Helligkeit unabhängig von der Farbe ist)

Update / Verbesserungen:

Nachdem ich diese Methode eine Weile benutzt hatte, bemerkte ich einige Verbesserungen, die durchgeführt werden können

  • replacing GetPixel für mehr Leistung
  • Verwenden Sie das exeif-thumbnail anstatt das gesamte Bild zu lesen, um die Leistung zu verbessern
  • 0.5f anstelle von 0.5f für Hell- und 0.5f die unterschiedliche mittlere Helligkeit aller 256 Pixel. Ansonsten werden dunkle / helle Bilder als gleich angenommen und es können Bilder mit veränderter Helligkeit erkannt werden.
  • Wenn Sie fast Berechnungen benötigen, verwenden Sie bool[] oder List<bool> Wenn Sie viele Hashes speichern müssen, um Speicherplatz zu sparen, verwenden Sie ein Bitarray da ein Boolescher Bitarray nicht in einem Bit gespeichert wird, sondern ein byte .

Ich schreibe ein Tool in C #, um doppelte Bilder zu finden. Derzeit erstelle ich eine MD5-Prüfsumme der Dateien und vergleiche diese.

Leider können meine Bilder sein

  • um 90 Grad gedreht
  • unterschiedliche Abmessungen haben (kleineres Bild mit gleichem Inhalt)
  • haben unterschiedliche Komprimierungen oder Dateitypen (zB JPEG-Artefakte, siehe unten)

Was wäre der beste Ansatz, um dieses Problem zu lösen?


Interessante Frage, der Vergleich von Bildern ist nicht so schwer, da,

  1. Diese Bilder sind die gleichen (das erste ist kein Abschnitt des zweiten oder umgekehrt)
  2. Die Bilder werden nur um ein Vielfaches von 90 Grad gedreht

Ein Vergleich wäre,

  1. Stellen Sie beide Bilder auf die niedrigste Diamentiongröße ein
  2. Anwenden der Kantenerkennung auf jedes resultierende Schwarzweißbild (oder Array von 0 und 1)
  3. Vergleichen Sie die resultierenden Bitmaps (lassen Sie die erste ruhig und drehen Sie die zweite dreimal um 90 Grad) und berechnen Sie die% passenden Pixel, um den höchsten Wert zu erhalten

Wenn der Wert innerhalb eines vernünftigen Bereichs von 90% liegt (muss wahrscheinlich durch wenige Experimente ermittelt werden), können Sie davon ausgehen, dass beide Werte identisch sind. Dies funktioniert jedoch nicht, wenn:

  1. Selbst wenn sich einige Pixel in der Ecke befinden, wird beispielsweise das zweite Bild vom ersten Bild abgeschnitten
  2. Bilder werden nicht um ein Vielfaches von 90 Grad gedreht (obwohl dies nicht sehr wahrscheinlich ist)

Sie können den Algorithmus zum Vergleichen von zwei Bildern aktivieren, um die verfügbaren Methoden für den Bildvergleich anzuzeigen.

Sofern Sie nicht die vollständigen Algorithmen selbst neu erstellen möchten, sollten Sie versuchen, bereits vorhandene Bibliotheken oder einen Teil ihres Codes zu verwenden (sofern die Lizenz für Sie in Ordnung ist).

Für eine Open Source C # EmguCV von Edge Detection und verwandten Computer Vision-Algorithmen können Sie EmguCV ausprobieren, ein Wrapper von OpenCV.





hash