comparing images - listing pixel differences

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?".
Post Reply
sheepshearer

comparing images - listing pixel differences

Post by sheepshearer »

when comparing two images, can anyone tell me how i might be able to list pixel differences?

for instance, i'd like to see something like a unix diff that i'll call myimdiff:

Code: Select all

$ myimdiff ref.png new.png
(12,34)
< RGB: 255 255 255
---
> RGB: 255 255 253
(56,78)
< RGB: 255 255 255
---
> RGB: 0 0 0
is anything like this possible?

thanks
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: comparing images - listing pixel differences

Post by fmw42 »

sheepshearer wrote:when comparing two images, can anyone tell me how i might be able to list pixel differences?

for instance, i'd like to see something like a unix diff that i'll call myimdiff:

Code: Select all

$ myimdiff ref.png new.png
(12,34)
< RGB: 255 255 255
---
> RGB: 255 255 253
(56,78)
< RGB: 255 255 255
---
> RGB: 0 0 0
is anything like this possible?

thanks
Do you want to detect the difference for only one given pixel coordinate or all different pixels in the image.

Test images:

convert rose: rose1.png

make top row white
convert rose: -gravity north -chop 0x1 -background white -splice 0x1 +repage rose2.png

For the former (difference at pixel 10,0, ie. top row 11th pixel)
infile1="rose1.png"
infile2="rose2.png"
x=10
y=0
convert $infile1[1x1+${x}+${y}] $infile2[1x1+${x}+${y}] -format \
"%[fx:floor(255*(u.r-v.r))],%[fx:floor(255*(u.g-v.g))],%[fx:floor(255*(u.b-v.b))]" info:


For the latter:

infile1="rose1.png"
infile2="rose2.png"
convert $infile1 $infile2 -fx "u!=v?debug(floor(255*(u-v))):0" null:

Note in the latter, coordinates which are different are listed as y,x.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: comparing images - listing pixel differences

Post by anthony »

You can just use 'diff' or a GUI diff on the output of a 'txt:' format version of the images.

Code: Select all

convert  image1.png  -depth 8 image1.txt
convert  image2.png  -depth 8 image2.txt
diff image1.txt image2.txt

to find what pixels are different and my how much, consider using 'compare'
or a -compose Difference merger of the two images.

See IM Examples, Comparing images.
http://www.imagemagick.org/Usage/compare/
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
sheepshearer

Re: comparing images - listing pixel differences

Post by sheepshearer »

Code: Select all

convert  image1.png  -depth 8 image1.txt
convert  image2.png  -depth8 image2.txt
diff image1.txt image2.txt
thanks! that's perfect. i didn't know about the txt: enumeration format. i thought i would have to do something like convert to a text ppm format and diff that way.

example output for the record:

Code: Select all

$ diff ref.txt new.txt 
1163c1163
< 3,3: (128, 11,  0, 79)  #800B00B0  rgba(128,11,0,0.309804)
---
> 3,3: (255,255,255,  0)  #FFFFFF  white
1936c1936
< 4,5: (128, 11,  0, 79)  #800B00B0  rgba(128,11,0,0.309804)
---
> 4,5: (255,255,255,  0)  #FFFFFF  white
1947c1947
< 15,5: (128, 11,  0, 79)  #800B00B0  rgba(128,11,0,0.309804)
---
> 15,5: (255,255,255,  0)  #FFFFFF  white
2709c2709
< 5,7: (128, 11,  0, 79)  #800B00B0  rgba(128,11,0,0.309804)
---
> 5,7: (255,255,255,  0)  #FFFFFF  white
2720c2720
< 16,7: (128, 11,  0, 79)  #800B00B0  rgba(128,11,0,0.309804)
---
> 16,7: (255,255,255,  0)  #FFFFFF  white
3482c3482
< 6,9: (128, 11,  0, 79)  #800B00B0  rgba(128,11,0,0.309804)
---
> 6,9: (255,255,255,  0)  #FFFFFF  white
3493c3493
< 17,9: (128, 11,  0, 79)  #800B00B0  rgba(128,11,0,0.309804)
---
> 17,9: (255,255,255,  0)  #FFFFFF  white
4266c4266
< 18,11: (128, 11,  0, 79)  #800B00B0  rgba(128,11,0,0.309804)
---
> 18,11: (255,255,255,  0)  #FFFFFF  white
i can push that through Perl scripts and automate some useful stuff now.

thanks both!
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: comparing images - listing pixel differences

Post by anthony »

That is good.

For more info on that format see IM Examples, File Handling, Special File Formats, TXT
http://www.imagemagick.org/Usage/files/#txt

Do not relay on the format after the values in parenthesis, as that is comment on other methods of representing that color at that depth,
This will vary quite a but. The pixel location and color values in the parenthesis however will be correct.


As mentioned getting the TXT output of a Difference image may be better as it returns how different the values are. this means you get one file with zeros for no change, and increasing numbers for larger changes. This allows you to discount small non-visible differences between the two image.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: comparing images - listing pixel differences

Post by fmw42 »

Here are two more ways, based upon my original and Anthony's ideas using txt


# list only different pixels
convert rose: rose1.png
convert rose: -gravity north -chop 0x1 -background white -splice 0x1 +repage rose2.png
infile1="rose1.png"
infile2="rose2.png"
convert $infile1 $infile2 -compose difference -composite miff:- | convert - -fx "u!=0?debug(255*u):0" null:


# list all pixels with black as no difference
convert rose: -depth 8 rose1.png
convert rose: -gravity north -chop 0x1 -background white -splice 0x1 +repage -depth 8 rose2.png
infile1="rose1.png"
infile2="rose2.png"
convert $infile1 $infile2 -compose difference -composite txt:-
Post Reply