Compare two images and get the difference

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
lusky
Posts: 10
Joined: 2012-04-14T05:43:05-07:00
Authentication code: 8675308
Location: Lenart, Slovenia

Compare two images and get the difference

Post by lusky »

Hey everybody.
I have made some tests about the quality of video codecs and now I want to see the diference betwen these.
So what I want to do is:
I have a original image and a encodec image. All images are jpg. Now I want to see the diference betwen the original image and the encodec. It will be good if I can see how the pixels changed or where in the picture are the most errors after the encoding. It will also be good if the image can be represented in grayscale. Also it will be good if the program can represent me a number that will tell me how similar the images are in % or how many errors are or how similar they are. Something in that way will be great. Hope you understand what I'm doing and what I want.
If someone knows the answear, please post me the commands for command line.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Compare two images and get the difference

Post by fmw42 »

If the images are the same size, then

compare -metric rmse image1 image2 diffimage

see
http://www.imagemagick.org/script/compare.php
http://www.imagemagick.org/Usage/compare/
lusky
Posts: 10
Joined: 2012-04-14T05:43:05-07:00
Authentication code: 8675308
Location: Lenart, Slovenia

Re: Compare two images and get the difference

Post by lusky »

What means the number after the compresion?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Compare two images and get the difference

Post by fmw42 »

lusky wrote:What means the number after the compresion?
The numbers resulting from the command are the error measure. In the case I specified it is rmse (root mean squared error). The first value is in absolute graylevel per your IM compile quantum level (default is Q16) so the result will between 0 and 65535. The second number in parenthesis, is the error in the range of 0 to 1. So multiply it by 100 to get percent.

You can choose different error measure as per the links I listed above.
lusky
Posts: 10
Joined: 2012-04-14T05:43:05-07:00
Authentication code: 8675308
Location: Lenart, Slovenia

Re: Compare two images and get the difference

Post by lusky »

Thank you for that opinion. I'm very new in all this thinks, so I will maybe ask you some stupit questions :(
That what you wrote to me was very helpfull. Can you please explain this numbers more easier-otherwise?
So if the difference between the pictures are small the first number should be a lower number or higher number?
The second number is the error number of the pixels that had changed between the encoding?
The thirt question is: The image that we get after comparing, shows the difference (white dots) that have been detected or something alse? Because if I compare a bad image with the original a get very small numbers of white dots. But when I compare almost the same image with the original there are more white dots. That is very strange. Can you explain me this please?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Compare two images and get the difference

Post by fmw42 »

Both numbers represent the error. The second one is in the range of 0 to 1. The first one is the same but multiplied by 65535 in you are running the default IM in Q16 mode so that the values range from 0 to 65535. If in Q8 mode, then the first number will be in the range of 0 to 256. In both cases, the smaller the number (for RMSE metric), the more the images are the same. Or the more the difference, the larger the numbers will be.

The difference images shows the image that has been whitened and the locations where there are difference are shown in red (unless you specify some other color). If you want the difference image to be black and white, with white where there are differences, then you need to post process that image to make all colors black that are not pure red and make the red into white.

convert diffimage.png -fill black +opaque red -fill white -opaque red bwdiffimage.png

see
http://www.imagemagick.org/Usage/color_basics/#replace
lusky
Posts: 10
Joined: 2012-04-14T05:43:05-07:00
Authentication code: 8675308
Location: Lenart, Slovenia

Re: Compare two images and get the difference

Post by lusky »

Thak you very much. You are the best :D

Is there a command whit which I can count the number of pixels that have changed. And a command whit which I can count the number of all pixels that are in the original image, so that I have a reference of the number of all pixels that are in the original image and then the number of changed pixels. For example that I can than say, the number of pixels is 5000000 and after encoding 850000 pixels have changed?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Compare two images and get the difference

Post by fmw42 »

lusky wrote:Thak you very much. You are the best :D

Is there a command whit which I can count the number of pixels that have changed. And a command whit which I can count the number of all pixels that are in the original image, so that I have a reference of the number of all pixels that are in the original image and then the number of changed pixels. For example that I can than say, the number of pixels is 5000000 and after encoding 850000 pixels have changed?

The second number which comes from the compare is the fraction of all pixels that have changed. So just multiply by the width*height of the image to find out all pixels that have changed. The produce of the width*height is the total number of image pixels.

This is unix. If on windows, you need to see syntax difference for variables at http://www.imagemagick.org/Usage/windows/

fraction=`compare -metric rmse image1 image2 null: 2>&1 | sed -n 's/.*(\(.*\))/\1/p'`
numchanged=`convert xc: -format "%[fx:$fraction*w*h]" info:`
totpix=`convert xc: -format "%[fx:w*h]" info:`

echo "fraction=$fraction; numchanged=$numchanged; totpix=$totpix"

The first line above to get fraction, gets the results from the compare, converts it so it gets captured and then pipes to sed to extract just the second number. Note the null: rather than diffimage, in case, you only want the numbers and don't want to save the diffimage.


see fx calculations at
http://www.imagemagick.org/Usage/transform/#fx
http://www.imagemagick.org/script/fx.php

P.S.

Actually the following is not a proper measure of the number of pixels that are different.

numchanged=`convert xc: -format "%[fx:$fraction*w*h]" info:`

See later posts for a more correct measure.
Last edited by fmw42 on 2012-04-16T18:19:50-07:00, edited 1 time in total.
lusky
Posts: 10
Joined: 2012-04-14T05:43:05-07:00
Authentication code: 8675308
Location: Lenart, Slovenia

Re: Compare two images and get the difference

Post by lusky »

Therefore if I understand you right it is so:
Both image resolutions are 1920x1080. If I multiply 1920*1080 I will get the number of all pixel, right? In my case it will be 1920*1080=2073600 pixels
After the compare the number in the parenthesis is 0,0121116 or 1,21116%. Now I must multiply this number with the number of all pixel. And that will be 2073600*0,0121116=25114,61376 pixels have changed.
Is that so right or have I misunderstood you?


The second thing I don't understand is your post:
fraction=`compare -metric rmse image1 image2 null: 2>&1 | sed -n 's/.*(\(.*\))/\1/p'`
numchanged=`convert xc: -format "%[fx:$fraction*w*h]" info:`
totpix=`convert xc: -format "%[fx:w*h]" info:`

If I entered it in that way it doesn't work. The first one "compare -metric rmse image1 image2 null: 2>&1 | sed -n 's/.*(\(.*\))/\1/p'" work if I don't enter | sed -n 's/.*(\(.*\))/\1/p' I even don't now what this mean.
The second and third one works, but I don't know where to put the difference image in?

Is there any change that the difference image will show me only the difference where the pixels have changed? Not all difference only where the pixel has changed?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Compare two images and get the difference

Post by fmw42 »

lusky wrote:Therefore if I understand you right it is so:
Both image resolutions are 1920x1080. If I multiply 1920*1080 I will get the number of all pixel, right? In my case it will be 1920*1080=2073600 pixels
After the compare the number in the parenthesis is 0,0121116 or 1,21116%. Now I must multiply this number with the number of all pixel. And that will be 2073600*0,0121116=25114,61376 pixels have changed.
Is that so right or have I misunderstood you?
Yes, exactly.

lusky wrote:The second thing I don't understand is your post:
fraction=`compare -metric rmse image1 image2 null: 2>&1 | sed -n 's/.*(\(.*\))/\1/p'`
numchanged=`convert xc: -format "%[fx:$fraction*w*h]" info:`
totpix=`convert xc: -format "%[fx:w*h]" info:`
Try this:

compare -metric rmse rose: rose: null: 2>&1 | sed -n 's/.*(\(.*\))/\1/p'

It should return 0. If not, then perhaps your unix does not have sed. The sed command simply returns the value in the parenthesis

compare -metric rmse rose: rose: null:
0 (0)

compare -metric rmse rose: rose: null: 2>&1 | sed -n 's/.*(\(.*\))/\1/p'
0

I am not sure why it would not work for you.

But try this instead

convert rose: rose.jpg
compare -metric rmse rose: rose.jpg null: 2>&1 | tr "(" "\000" | tr ")" "\000" | cut -d\ -f2

If that works, then replace the sed ... with tr "(" "\000" | tr ")" "\000" | cut -d\ -f2 in the above code


lusky wrote:If I entered it in that way it doesn't work. The first one "compare -metric rmse image1 image2 null: 2>&1 | sed -n 's/.*(\(.*\))/\1/p'" work if I don't enter | sed -n 's/.*(\(.*\))/\1/p' I even don't now what this mean.
The second and third one works, but I don't know where to put the difference image in?
If you replace the null: with diffimage.png, you will get the two resulting images as well as the numbers.
lusky wrote:Is there any change that the difference image will show me only the difference where the pixels have changed? Not all difference only where the pixel has changed?
just use:

compare -metric rmse image1 image2 diffimage

This image will be bright red where there are differences in the the pixels, but it will be overlayed on top of the first image which has been whitened.

As I explained earlier, if you just want to see a black and white image where the differences are located, then use

convert diffimage-0.png -fill black +opaque red -fill white -opaque red bwdiffimage.png
lusky
Posts: 10
Joined: 2012-04-14T05:43:05-07:00
Authentication code: 8675308
Location: Lenart, Slovenia

Re: Compare two images and get the difference

Post by lusky »

Like you sad my unix doesn't suport sed and tr. It said 'sed' is not recognized as an internal or external command,operable program or batch file. I get the same for tr. But OK the things aren't so importand for me.

What I don't understand is that I have most of the image red, but the number of changed pixels is 1,21116%? I would say that I don't know 70% or 80% have changed. Can you please explain me this?
Like you said the red color indicates the changed pixels and the white indicates the pixels that haven't changed.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Compare two images and get the difference

Post by fmw42 »

If the pixels are even 1 graylevel different, then I think they get colored red.

Can you post links to your two images that you are comparing? That way we can see what you are looking at and test ourselves.
lusky
Posts: 10
Joined: 2012-04-14T05:43:05-07:00
Authentication code: 8675308
Location: Lenart, Slovenia

Re: Compare two images and get the difference

Post by lusky »

I don't know where to post there. Can you help me? Can you send me your email or something else?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Compare two images and get the difference

Post by fmw42 »

lusky wrote:I don't know where to post there. Can you help me?
You have to find some free image hosting site (such as dropbox) or any others. You can find them by searching with google. Upload your photos there and put a link here to where you uploaded. Be sure others do not need a login or password to download your image or access the page from which it is downloaded.
lusky
Posts: 10
Joined: 2012-04-14T05:43:05-07:00
Authentication code: 8675308
Location: Lenart, Slovenia

Re: Compare two images and get the difference

Post by lusky »

How many graylevels are? How much must the pixel change that the program count it. Like I sayd the number is 1,2%? If it grayscale it just for 1 level, how much must it be to count it?
Post Reply