Compare images to find differences in C#

[compare images]

This example lets you compare images to see if they are the same. When you select two images to compare and click the Go button, the program executes the following code to compare the images and see at which pixels they differ.

private void btnGo_Click(object sender, EventArgs e)
{
    this.Cursor = Cursors.WaitCursor;
    Application.DoEvents();

    // Load the images.
    Bitmap bm1 = (Bitmap)picImage1.Image;
    Bitmap bm2 = (Bitmap)picImage2.Image;

    // Make a difference image.
    int wid = Math.Min(bm1.Width, bm2.Width);
    int hgt = Math.Min(bm1.Height, bm2.Height);
    Bitmap bm3 = new Bitmap(wid, hgt);

    // Create the difference image.
    bool are_identical = true;
    Color eq_color = Color.White;
    Color ne_color = Color.Red;
    for (int x = 0; x < wid; x++)
    {
        for (int y = 0; y < hgt; y++)
        {
            if (bm1.GetPixel(x, y).Equals(bm2.GetPixel(x, y)))
                bm3.SetPixel(x, y, eq_color);
            else
            {
                bm3.SetPixel(x, y, ne_color);
                are_identical = false;
            }
        }
    }

    // Display the result.
    picResult.Image = bm3;

    this.Cursor = Cursors.Default;
    if ((bm1.Width != bm2.Width) || (bm1.Height != bm2.Height)) are_identical = false;
    if (are_identical)
        lblResult.Text = "The images are identical";
    else
        lblResult.Text = "The images are different";
}

The code loads the two image files into Bitmaps. It finds the smaller of the Bitmaps’ widths and heights, and makes a new Bitmap of that size.

Next the program loops over the pixels in the smaller area, comparing the images’ pixels. If two corresponding pixels are equal, the program colors the result pixel white. If the two pixels are different, the program makes the result pixel red. When it has examined all of the pixels, the program displays the result image.

The result image highlights differences between the two input images no matter how small the differences are. If a pixel in one image has RGB values 50, 150, 200 and the corresponding pixel in the other image has RGB values 51, 150, 200, the result shows the difference plainly even though you won’t be able to tell the difference with your eyes in the original images.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in graphics, image processing and tagged , , , , , , , , , . Bookmark the permalink.

11 Responses to Compare images to find differences in C#

  1. Mark says:

    Nice example. Question though: if the images are photographs that were captured at slightly different frames of reference (in other words my camera moved ever so slightly between shots), what strategy would you take to get both images lined up before running this comparison?

  2. Rod Stephens says:

    This technique doesn’t really work for that. However, you could try transforming the image in various ways to see if you can minimize the difference. For example, try offsetting one image by 1 or 2 pixels in the +/- X and Y directions and adding up the total differences. You might also rotate the image slightly, although that takes a bit longer.

    (I think this technique was originally developed to find differences in telescope images to find moving objects such as planets, asteroids, and novas. There the telescope should be in exactly the same orientation for each picture and even if it’s not you can use the stars to align the images. I suppose you could use objects in the scene to align the images more generally if you can figure out how. I may have to think about that…)

  3. Mark says:

    Interesting – I’ll consider that. I’m thinking it would be really powerful to be able to align and then compare two selection areas of two images, rather than the whole images. In that case there would need to be some creative approach, probably using advanced math functions(?) to look through each selection area to find similarities between the two. Having identified the similar areas, a reference pixel could be established (ie top left most pixel included in region of similarity) then the comparison could align and proceed based on that pixel. Any thoughts on likelihood of success and angle of approach? Thanks!

  4. Rod Stephens says:

    I think this could be a big area of research. If you don’t know whether the images are related, you might need an algorithm that performed feature identification to try to determine what kinds of objects are present. For example, it’s easy for a person to tell if the Eiffel Tower is in a picture but it would be tricky to write a program to do so if the pictures were taken at different angles. There is software that does this sort of thing remarkably well but I couldn’t write something like that.

    It wouldn’t be too hard to let the user select two areas to compare.

    Then I would look for bright spots or perhaps areas of sudden contrast and try to line those up. It might be worth doing some image pre-processing such as using an edge detector to remove a lot of the data from the pictures. Then it might be easier to match them up.

    In the end you would have to try some changes between the two images (move them around and rotate them) to see which gives the best result. You *might* be able to get a gradient of improvement. I.e. if moving +1 in the X direction helps, do it again until it stops helping. I suspect the gradient won’t last long, though, unless it’s a very smoothly colored image.

    I’m sure you could get something to work. I’m just not sure how fast it would be.

    (A cool problem would be to assemble a panoramic view taken in several pictures by a camera.)

    (A related problems that I’ve always thought would be fun would be to assembly a jigsaw puzzle from an image of the pieces. It would be sort of similar–trying to match up corresponding parts of pieces–although the edges would be well-defined so it would be a lot easier.)

    Sorry I don’t have any concrete code. It would be fun to work on if I only had the time 😉

  5. Rod Stephens says:

    I had two other thoughts. First, if you need to worry about scaling, that adds a whole new level of complexity. I assume these images are probably taken at the same scale and distance from the subject. If not, you would need to try different scaling levels in addition to offsets and rotations.

    Second, you could probably scale the images to make them smaller before trying to find the parts that line up. If two images line up at a certain position, then their scaled versions should also line up at the scaled position. That would give you much less data to compare. After you find a good match, you could verify it on the original images.

  6. Mark says:

    Great thoughts Rod. Thanks very much for taking the time to respond. If I have some success I’ll respond back.

    I did find this site:
    http://elastix.isi.uu.nl/index.php Elastix appears to be a wrapper around more powerful image analysis tools designed for this kind of thing. It may be something I can integrate though it’s not .net code, even if only to drop out to cmdline to crunch the data, then feed parameters back into the comparison code. We’ll see!

    Thanks again
    Mark

  7. leena says:

    please help me ,, i need to make a program that compare to images and give the result from database ,,

    • RodStephens says:

      You can use this example to compare the images. Then you’ll have to write the result into the database.

      Or you could add up the number of pixels where the images differ or calculate some other measurement of their differences and store that as a number instead of an image. That would take less space and would let you query for things like images that differ by less than a certain amount.

  8. abeer says:

    please, help me .. I need to make a program that compare two images that captured with different angels and show the differences in pixels .

    • RodStephens says:

      Sorry but I don’t know how to do that. You would need to know the angle from which the pictures were taken and transform them so they were viewed from approximately the same angle. But a pixel-by-pixel comparison probably won’t work anyway.

Leave a Reply

Your email address will not be published. Required fields are marked *