2010-08-02 15 views

Antwort

12

Sie können eine Reihe von Tools mit der Bezeichnung TestApi verwenden, die eine Open-Source-Bibliothek zur Unterstützung von Komponententests ist. Eines dieser API wird Visual Verification API genannt, und es tut genau das, was Sie brauchen - es zwei Bilder, die Sie vergleichen können und sagen, ob sie gleich sind:

// 1. Capture the actual pixels from a given window 
Snapshot actual = Snapshot.FromRectangle(new Rectangle(0, 0, 100, 100)); 

// 2. Load the reference/master data from a previously saved file 
Snapshot expected = Snapshot.FromFile("Expected.png")); 

// 3. Compare the actual image with the master image 
// This operation creates a difference image. Any regions which are identical in 
// the actual and master images appear as black. Areas with significant 
// differences are shown in other colors. 
Snapshot difference = actual.CompareTo(expected); 

// 4. Configure the snapshot verifier - It expects a black image with zero tolerances 
SnapshotVerifier v = new SnapshotColorVerifier(Color.Black, new ColorDifference()); 

// 5. Evaluate the difference image 
if (v.Verify(difference) == VerificationResult.Fail) 
{ 
    // Log failure, and save the diff file for investigation 
    actual.ToFile("Actual.png", ImageFormat.Png); 
    difference.ToFile("Difference.png", ImageFormat.Png); 
} 
4

Der einfachste Ort zum Starten wäre Dimensionen. Wenn die Dimensionen nicht gleich sind, können Sie sie möglicherweise als false deklarieren.

Wenn Sie Pixel für Pixel durchlaufen müssen, benötigen Sie zwei For-Schleifen. Etwas in dieser Richtung:

Bitmap ImageA... 
Bitmap ImageB... 

for (Int64 x = 0; x < ImageA.Width; x++) 
{ 
    for (Int64 y = 0; y < ImageA.Height; y++) 
    { 
     if (ImageA.GetPixel(x, y) != ImageB.GetPixel(x, y)) 
     { 
      return false; 
     } 
    } 
} 

Es ist Pseudo-Code (die Funktionen existieren in C#, obwohl ich sie nicht im Moment erinnern kann) und sehr simpel, ist aber, wie man eine grundlegende Pixel ausführen wollen würde -zu-Pixel-Prüfung.

Beachten Sie jedoch, dass für diese Schleife die Bilder die gleichen Abmessungen haben müssen. Wenn dies nicht der Fall ist, erhalten Sie wahrscheinlich Ausnahmen, wenn Sie versuchen, ein Pixel außerhalb des Bereichs des kleineren Pixels zu erfassen. Es wird auch nicht sehr schnell sein, die Pixel zu vergleichen, daher sollten Sie vielleicht zuerst eine andere Möglichkeit finden, mögliche Duplikate zu verwerfen.

Edit: Ich bin mir nicht sicher, wie man dies auf einer Image, aber es ist ganz einfach für Bitmap s. Es gibt keine sichtbare Möglichkeit, Bildpixeldaten aus der Klasse zu entfernen. Es scheint, dass die Bitmaps von Images erben, so dass dies immer noch funktioniert. Da Bilder sowohl für Bitmaps als auch für Metadateien eine abstrakte Klasse sind, verfügen sie möglicherweise nicht über eine einfache interne Pixelliste.

+4

Also, ich will nur erwähnen, dass, wenn die beiden Bilder relativ groß sind, dies als ein Hund langsam. Ich würde Lockbits verwenden und auch Zeile für Zeile durchlaufen statt Spalte, so wie es im Speicher angeordnet wird. –

1

ich die gleiche Frage noch heute hatte, war meine Abhilfe zu nehmen image1 und image2 konvertiert in 256x256 oder 128x128 beide übersetzt und dann ein Bild3 mit der Differenz zwischen ihnen, dann Scan Bild3 Überprüfung der Unterschiede und Rückgabe der Differenzbetrag, fand ich, dass die geringere Differenz in% mehr gleich die Bilder sind und mehr wahrscheinlich für sie gleich sein. Auf diese Weise können Sie feststellen, ob Bilder gleich sind, auch wenn sie unterschiedlich groß sind. Hier ist der Code.

double CompareImages(Bitmap InputImage1, Bitmap InputImage2, int Tollerance) 
    { 
     Bitmap Image1 = new Bitmap(InputImage1, new Size(128, 128)); 
     Bitmap Image2 = new Bitmap(InputImage2, new Size(128, 128)); 
     int Image1Size = Image1.Width * Image1.Height; 
     int Image2Size = Image2.Width * Image2.Height; 
     Bitmap Image3; 
     if (Image1Size > Image2Size) 
     { 
      Image1 = new Bitmap(Image1, Image2.Size); 
      Image3 = new Bitmap(Image2.Width, Image2.Height); 
     } 
     else 
     { 
      Image1 = new Bitmap(Image1, Image2.Size); 
      Image3 = new Bitmap(Image2.Width, Image2.Height); 
     } 
     for (int x = 0; x < Image1.Width; x++) 
     { 
      for (int y = 0; y < Image1.Height; y++) 
      { 
       Color Color1 = Image1.GetPixel(x, y); 
       Color Color2 = Image2.GetPixel(x, y); 
       int r = Color1.R > Color2.R ? Color1.R - Color2.R : Color2.R - Color1.R; 
       int g = Color1.G > Color2.G ? Color1.G - Color2.G : Color2.G - Color1.G; 
       int b = Color1.B > Color2.B ? Color1.B - Color2.B : Color2.B - Color1.B; 
       Image3.SetPixel(x, y, Color.FromArgb(r,g,b)); 
      } 
     } 
     int Difference = 0; 
     for (int x = 0; x < Image1.Width; x++) 
     { 
      for (int y = 0; y < Image1.Height; y++) 
      { 
       Color Color1 = Image3.GetPixel(x, y); 
       int Media = (Color1.R + Color1.G + Color1.B)/3; 
       if (Media > Tollerance) 
        Difference++; 
      } 
     } 
     double UsedSize = Image1Size > Image2Size ? Image2Size : Image1Size; 
     double result = Difference*100/UsedSize; 
     return Difference*100/UsedSize; 
    } 

hier Getestet mit mehr als 900 Bildern und es wirkt wie ein Zauber x)

Verwandte Themen