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;

    // 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);
                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";
        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.

15 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: 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

  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 .

  9. This is a very weak comparison method. Rather than using this way, you can check crc32 of two different images if the file type is not a concern…

    • RodStephens says:

      Actually this is stronger than a CRC for two reasons. First, a CRC may (rarely) incorrectly decide that two files are the same when they are not.

      More importantly, this method shows where the two images are different. A CRC only shows that they are different.

      A CRC is much faster, however, so it’s a better method if you just want to know whether the two files are probably the same.

      For an example that uses a hash function similar to a CRC, see the post:

      Find duplicate files in C#, Part 4 of 4

  10. Daniel says:

    Pls I am working on a project with the topic: similarity measure for retrieving image from a database and I was asked to come up with two methods. Any idea about the methods that can go with the topic

    • RodStephens says:

      This can be tricky because comparing corresponding pixels in two images can take a long time for larger images.

      One approach would be to make a condensed representation of the images, sort of like a hash code. One way to do that would be to make reduced-scale thumbnail images and store them in the database. Then you can compare the thumbnails.

      Another way to condense the images would be to calculate the average colors of the pixels and store the average red, green, and blue values. Then to compare two images you could compare their saved values.

      A different approach would be to analyze the images like Google Image Search does to store a list of items in the image, such as “boat” and “water.” Then you could compare the key elements. That may be the best approach (depending on exactly what you want), but it is also certainly the hardest.

      You might also be able to use palette minimization to find the colors that are most important to the images and store that. For example, one image’s main colors might be red, pink, light blue, and yellow. Then you could compare those colors for two different images.

      If you want to know if two images are *exactly* equal, you could create a binary representation (like a bitmap) of each and hash them. Then you can see if their hash codes match. You might want to also compare their pixels to be absolutely certain that they match, but hash codes would make a very fast first test.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.