2010-08-02 41 views

Respuesta

12

Puede usar un conjunto de herramientas llamado TestApi, que es una biblioteca de fuente abierta para ayudar a las pruebas de unidades. Uno de tales API se llama Visual Verification API, y lo hace exactamente lo que necesita - puede comparar dos imágenes y le dirá si son iguales:

// 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

El lugar más simple para comenzar serían las dimensiones. Si las dimensiones no son iguales, puede declararlas falsas.

Si necesita recorrerlos píxel por píxel, necesitará dos bucles for. Algo a lo largo de estas líneas:

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 pseudo-código (existen las funciones en C#, aunque no puedo recordar que por el momento) y muy simplista, pero es la forma en que te gustaría realizar un píxel básica cheque a pixel.

Tenga en cuenta, sin embargo, para que ese bucle funcione las imágenes deben ser de las mismas dimensiones. Si no lo son, es probable que obtenga excepciones si intenta tomar muestras de un píxel fuera del área de la persona más pequeña. Tampoco será terriblemente rápido comparar los píxeles, por lo que es posible que desee encontrar otra forma de descartar posibles duplicados primero.

Editar: No estoy seguro de cómo hacer esto en un Image, pero es bastante simple para Bitmap s. No hay una forma visible de obtener datos de píxeles de la imagen fuera de la clase. Sin embargo, parece que Bitmaps hereda de Images, por lo que puede funcionar. Dado que las imágenes son una clase abstracta para los mapas de bits y metarchivos, es posible que no tengan una lista de píxeles internos simple.

+4

lo tanto, sólo mencionaremos que si las dos imágenes son relativamente grandes, esto va a ser lento como un perro. Yo usaría Lockbits y también recorrería por fila en lugar de columna, ya que así es como se organizará en la memoria. –

1

que tenían la misma pregunta el día de hoy, mi solución era tomar image1 e image2 convertidos a 256x256 o 128x128 ambos traducidos Y luego generan una image3 con la diferencia entre ellos, luego scan image3 revisando las diferencias y devolviendo la cantidad de diferencia, descubrí que la diferencia INFERIOR es en% más igual a las imágenes y más Probablemente para que sean iguales. De esta manera puede identificar si las imágenes son iguales, incluso si tienen un tamaño diferente. aquí está el código.

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

prueba aquí con más de 900 imágenes y funciona como un encanto x)

Cuestiones relacionadas