Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing two images using ImageMagick and C#

I want to compare two images and then generate and save an image that will show all the differences that has been found,

for example: enter image description here

I am using ImageMagick: https://magick.codeplex.com/ But they don't have full documentation for C#. I found only: http://www.imagemagick.org/Usage/compare/

This code for example show value from 0-1 that represent how similar the pictures are:

    MagickImage img1 = new MagickImage(@"C:\test\Image1.jpg");
    MagickImage img2 = new MagickImage(@"C:\test\Image2.jpg");
    double diff =  img1.Compare(img2,new ErrorMetric());

But how can I compare the images using ImageMagick and then save the result as shown in the example above and in their website?

Update: With the help of dlemstra I wrote the following code and I generate images that suppose to show the difference as in the example above. MagickImage img1 = new MagickImage(@"C:\test\Image1.jpg"); MagickImage img2 = new MagickImage(@"C:\test\Image2.jpg"); MagickImage img3 = new MagickImage(@"C:\test\Image3.jpg"); MagickImage img4 = new MagickImage(@"C:\test\DiffImage.jpg"); MagickImage img5 = new MagickImage(@"C:\test\DiffImage.jpg");

        var imgDiff = new MagickImage();

        img1.Compare(img2, new ErrorMetric(), imgDiff);
        imgDiff.Write(@"C:\test\Diff4.jpg");

        img1.Compare(img3, new ErrorMetric(), imgDiff);
        imgDiff.Write(@"C:\test\Diff5.jpg");

        img1.Compare(img4, new ErrorMetric(), imgDiff);
        imgDiff.Write(@"C:\test\Diff6.jpg");

        img5.Compare(img4, new ErrorMetric(), imgDiff);
        imgDiff.Write(@"C:\test\Diff7.jpg");

The Strange results are: When I compare the following two images with the marked only difference: enter image description here

This is the result that I get (And not as the example above from "imageMagick" enter image description here

like image 973
Yuval Levy Avatar asked Nov 01 '16 13:11

Yuval Levy


2 Answers

You will need to use one of the other overloads of the Compare method for this. The example below demonstrates how to do this:

using (var img1 = new MagickImage(@"C:\test\Image1.jpg"))
{
  using (var img2 = new MagickImage(@"C:\test\Image2.jpg"))
  {
    using (var imgDiff = new MagickImage())
    {
      double diff = img1.Compare(img2, new ErrorMetric(), imgDiff);
      imgDiff.Write(@"C:\test\Diff-Image1-Image2.jpg");
    }
  }
}

But when you are working with jpeg images (they are lossy) you probably also want to set the ColorFuzz on the first image:

img1.ColorFuzz = new Percentage(5); // adjust this value for your situation

This will make it so that pixels that are almost the same will also match.

like image 126
dlemstra Avatar answered Nov 05 '22 17:11

dlemstra


Lessons Learned:

Wanted to add some important notes so others hopefully avoid the pitfalls which I ran into when testing out ImageMagick (or any compare tool) for the first time.

  1. Beware of editing in Windows Paint in general.
  2. Don’t edit a *.png with a transparent background in Windows paint and expect a good compare. Windows Paint doesn’t handle transparent background and the png you edited in Paint will now have a white background. The Image will look exactly the same to the naked eye but the image comparers know better.
  3. If you have SnagIt, this is a better tool for making edits to an image when you want to put a image compare tool to the test.

Conclusion:

The code written by @dlemstra does work as expected. Just make sure that when you are testing out the first time that the second image (which you modified) didn’t get unintentionally modified by the image editor that you use. This is a general warning for when you are testing out any image compare tool for the first time to see if you want to use it or not.

Examples:

Example 1: Transparent png + Windows Paint

Downloading a transparent image, making and edit to it in Paint which unintentionally also changes background to white instead of transparent. Just by opening, then saving the second image in Paint without making any edits to the image will cause the diff to look like this:

enter image description here

I couldn’t figure out what was going on until I compared with Beyond Compare:

enter image description here

Example 2: Complex *.jpg + Windows Paint

Windows Paint was also not good at keeping complex images identical between saves: The big red areas were changes I had made, but the thin outlines of the roses were changes that Windows Paint made to the picture

enter image description here

Even when I made no changes at all and just open, saved and closed the second image in Paint (and the original image was an image which had also been saved in Paint), Paint still made undesired edits to the picture (dark red dots in image):

enter image description here

I then had an original image which had been saved in Paint and copied this image, opened the second image in snagIt, saved the second image in snagit, and then closed the image and compared the two images (which should have been identical). However, it seemed that snagIt made it’s own modifications to the original ‘Paint saved’ image:

enter image description here

Lastly, I copied the ‘Snagit saved’ image, opened this second image also in SnagIt, made an edit to the second image, saved the image in SnagIt and then closed the image. SnagIt did not make any modifications to this image and the compare showed exactly what I expected:

enter image description here

Lastly: Most information you find about ImageMagick pertains to using it via the command line. You can add the Magick.Net nuget to your C# project in Visual Studio by installing it via the NuGet Package Manager

enter image description here

like image 33
Fractal Avatar answered Nov 05 '22 16:11

Fractal