Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare Image objects with C# .NET? [closed]

Can we compare two Image objects with C#? For example, check whether they are equal, or even better check how similar are their pixels?

if possible, how?

like image 581
Louis Rhys Avatar asked Aug 02 '10 04:08

Louis Rhys


2 Answers

I had the same question this very day, my workaround was to take image1 and image2 converted to 256x256 or 128x128 both translated AND then generate an image3 with the difference between them, then scan image3 checking the differences and returning the difference amount, I found out that the LOWER difference amount in % more equal the images are and more likely for them to be equal. This way you can identify if images are equal even if they're differently sized. here is the 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;
    }

Tested here with over 900 images and it works like a charm x)

like image 194
Felype Avatar answered Sep 20 '22 02:09

Felype


You can use a set of tools called TestApi, which is an open-source library to aid unit testing. One of such API is called Visual Verification API, and it does exactly what you need - it can compare two images and tell you if they are equal:

// 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);
}
like image 24
Igal Tabachnik Avatar answered Sep 18 '22 02:09

Igal Tabachnik