Page 1 of 1
Subtracting two images
Posted: 2014-04-07T08:05:06-07:00
by WizardStan
I'm sorry, I know this question has been asked a lot, I've scoured the internet and come up with a lot of answers, but I'm obviously doing something very wrong because the results I'm getting aren't at all what are expected.
So I've got two images that are almost identical. The colours of one image have been slightly modified. I want to get these differences. Original image has a pixel value 200, modified image has pixel value 205, I want output to have 5. The direction doesn't matter, just the absolute difference (205 becoming 200 still should be 5). If the pixels are identical the output should be 0 (0-0 = 0, 255-255=0)
I thought that "compare -compose difference" would do this but the result isn't what I expected. I know the images are mostly identical except for a scattering of pixels, but I'm seeing differences in the output across the entire thing. As a test I even compared the image against itself expecting solid black output, but it did not.
Consider this example:
solid black bitmap
compare -compose difference black.bmp black.bmp black_diff.bmp
grey output
I also tried the same thing with a redish square (181,52,52) which produced teal output (95, 173, 173), then did a self difference on the teal square to get a kind of taupe (147, 100, 100), and then for good measure made duplicates of the images in case there's some problem with comparing a file directly against itself. I also tried "minus" and "subtract" and "exclusion" to no avail.
What am I misunderstanding? Is there a way to actually do what I want? If the two images are identical the output should be solid black.
"-compose src" does what I expect, showing me only the exact pixels that are different, but I want a little more information, the exact differences between those pixels.
Thanks for listening.
Re: Subtracting two images
Posted: 2014-04-07T10:21:14-07:00
by fmw42
What version of IM are you using and what platform? You may be seeing Q16 grayvalues (0-65535). Convert your results to 8-bit depth.
Code: Select all
convert -size 100x100 xc:black xc:"gray(5)" -depth 8 -compose difference -composite -verbose info:
Code: Select all
Channel statistics:
Gray:
min: 5 (0.0196078)
max: 5 (0.0196078)
mean: 5 (0.0196078)
standard deviation: 0 (0)
kurtosis: 0
skewness: 0
Code: Select all
convert -size 100x100 xc:"rgb(200,100,50)" xc:"rgb(205,90,70)" -depth 8 -compose difference -composite -verbose info:
Code: Select all
Channel statistics:
Red:
min: 5 (0.0196078)
max: 5 (0.0196078)
mean: 5 (0.0196078)
standard deviation: 0 (0)
kurtosis: 0
skewness: 0
Green:
min: 10 (0.0392157)
max: 10 (0.0392157)
mean: 10 (0.0392157)
standard deviation: 0 (0)
kurtosis: 0
skewness: 0
Blue:
min: 20 (0.0784314)
max: 20 (0.0784314)
mean: 20 (0.0784314)
standard deviation: 0 (0)
kurtosis: 0
skewness: 0
Re: Subtracting two images
Posted: 2014-04-07T10:41:49-07:00
by WizardStan
Debian Wheezy
Code: Select all
$ compare -version
Version: ImageMagick 6.7.7-10 2013-09-01 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
Features: OpenMP
"convert" is the same.
Here's something interesting.
Code: Select all
compare -compose difference black.bmp black.bmp black_diff.bmp
does what I described, producing unexpected colour differences even for the same file.
Code: Select all
convert -composite -compose difference black.bmp black.bmp black_diff.bmp
does exactly as the manual says, the output of my test files are what I'm expecting, and the same file twice outputs solid black.
I thought "compare" was basically a shortcut to "convert -composite" but there's something obviously wrong with that. What else is "compare" doing that makes it different from "convert -composite"? I tried specifying "-depth 8" but it didn't change anything.
Code: Select all
$ compare -compose difference black.bmp black.bmp black_diff.bmp -depth 8 -verbose info:
Image: black.bmp
Channel distortion: Undefined
Image: black.bmp
Format: BMP (Microsoft Windows bitmap image)
Class: DirectClass
Geometry: 64x64+0+0
Resolution: 28.35x28.35
Print size: 2.2575x2.2575
Units: PixelsPerCentimeter
Type: PaletteAlpha
Endianess: Undefined
Colorspace: sRGB
Depth: 8/4-bit
Channel depth:
red: 4-bit
green: 4-bit
blue: 4-bit
alpha: 1-bit
Channel statistics:
Red:
min: 204 (0.8)
max: 204 (0.8)
mean: 204 (0.8)
standard deviation: 0 (0)
kurtosis: 0
skewness: 0
Green:
min: 204 (0.8)
max: 204 (0.8)
mean: 204 (0.8)
standard deviation: 0 (0)
kurtosis: 0
skewness: 0
Blue:
min: 204 (0.8)
max: 204 (0.8)
mean: 204 (0.8)
standard deviation: 0 (0)
kurtosis: 0
skewness: 0
Alpha:
min: 255 (1)
max: 255 (1)
mean: 255 (1)
standard deviation: 0 (0)
kurtosis: 0
skewness: 0
Image statistics:
Overall:
min: 0 (0)
max: 204 (0.8)
mean: 153 (0.6)
standard deviation: 0 (0)
kurtosis: 0
skewness: 0
Colors: 1
Histogram:
4096: (204,204,204,255) #CCCCCC grey80
Rendering intent: Perceptual
Chromaticity:
red primary: (inf,inf)
green primary: (inf,inf)
blue primary: (5.03316e+06,2.01327e+06)
white point: (0.3127,0.329)
Interlace: None
Background color: white
Border color: srgba(223,223,223,1)
Matte color: grey74
Transparent color: none
Compose: Difference
Page geometry: 64x64+0+0
Dispose: Undefined
Iterations: 0
Compression: Undefined
Orientation: Undefined
Properties:
date:create: 2014-04-07T10:38:00-04:00
date:modify: 2014-04-07T10:38:00-04:00
signature: b145682b71b51f4fd0bd0fb5a92c0eb0656af164fa9a57c8400ff662f84f6dc5
Artifacts:
compose: difference
filename: black_diff.bmp
verbose: true
Tainted: True
Filesize: 0B
Number pixels: 4.1K
Pixels per second: 0B
User time: 0.010u
Elapsed time: 0:01.000
Version: ImageMagick 6.7.7-10 2013-09-01 Q16 http://www.imagemagick.org
Re: Subtracting two images
Posted: 2014-04-07T10:43:27-07:00
by fmw42
compare -compose difference black.bmp black.bmp black_diff.bmp
It is not compare, but composite that you want here
composite -compose difference black.bmp black.bmp black_diff.bmp
see
http://www.imagemagick.org/Usage/compose/#compose
I would avoid the composite format. It is old and not as flexible. Use the convert syntax. The composite syntax is likely to be deprecated if not removed in IM 7.
compare has a totally different syntax and is meant to get an overall metric of the image differences. That metric you may want is MAE, but is not on a channel by channel basis, but combined for all channels.
see
http://www.imagemagick.org/Usage/compare/
http://www.imagemagick.org/script/compare.php
Re: Subtracting two images
Posted: 2014-04-07T11:18:34-07:00
by WizardStan
ah, I see. Makes sense, makes sense.
Thanks a lot! I've got it all sorted out now.
Re: Subtracting two images
Posted: 2014-04-07T18:28:03-07:00
by anthony
The difference image that compare generates by default is a copy of the first image, with a semi transparent overlay of white and red marking what pixels are different for human visual view.
http://www.imagemagick.org/Usage/compare/#compare
There are options to adjust the overlaid colors (and there transparency) though at this time there is no way of specifying a named color with a certain amount of transparency. For example you can not easily specify "50% transparent red", except by using color values "#FF00007F", rgba(255,0,0,0.5). See
Semi-Transparent Colors
Difference images (from composition using a mathematical compose) are the absolute difference in image values.
http://www.imagemagick.org/Usage/compare/#difference
On the other hand if you really want what your thread title suggests,
subtracting two images. That would be using compose 'minus'.
http://www.imagemagick.org/Usage/compose/#minus
However remember that this can generate negative values. You can only handle negative values by using HDRI versions of IM,
OR by using a 'mathematical composition to subtract images, so as to use a mathematical 50% grey to represent zero, and scale the results by 50% to fit the normal image range of values
Code: Select all
convert xc:black xc:black \
-compose Mathematics -define compose:args='0,.5,-.5,.5' -composite \
txt:
# ImageMagick pixel enumeration: 1,1,65535,srgb
0,0: (32768,32768,32768) #800080008000 srgb(50.0008%,50.0008%,50.0008%)
Note this is also equivalent to this using the -poly weighted average operator (with a null: constant addition)
Code: Select all
convert xc:black xc:black null: -poly '0.5,1, -0.5,1, 0.5,0' txt:
And that is equivalent to negating the image to subtract, and averaging the two images!
Code: Select all
convert xc:black \( xc:black -negate \) -evaluate-sequence mean txt:
It like I often say...
There are lots of ways to skin a cat, and what method you use depends
on what you want that skin for, and how messy you like the results!
Re: Subtracting two images
Posted: 2015-03-06T08:56:11-07:00
by Deane
Hi, I am new to ImageMagick and I am trying to subtract one JPG image from another one. I have used some of the commands shown in the message above but none of them seem to work for me. Please take a look at the error messages I am getting and tell me what I am doing wrong. Thanks!
[img]C:\Horizon_photos\Cmd_window_errors.jpg[/img]
It doesn't look like I am using the Image command correctly to show the errors.
Re: Subtracting two images
Posted: 2015-03-06T09:04:43-07:00
by snibgo
Copy the text from the window, and paste it here.
Re: Subtracting two images
Posted: 2015-03-06T15:06:19-07:00
by Deane
OK, I figured out how to do that. You have to use a right-click menu, swipeing it does't work.
Thanks.
Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.
C:\Users\User>composite sky.jpg pelican.jpg \ -compose differnce dif.jpg
composite.exe: unable to open image `sky.jpg': No such file or directory @ error
/blob.c/OpenBlob/2674.
composite.exe: unable to open image `pelican.jpg': No such file or directory @ e
rror/blob.c/OpenBlob/2674.
composite.exe: unable to open image `\': No such file or directory @ error/blob.
c/OpenBlob/2674.
composite.exe: no decode delegate for this image format `' @ error/constitute.c/
ReadImage/501.
composite.exe: unrecognized compose operator `differnce' @ error/composite.c/Com
positeImageCommand/728.
C:\Users\User>composite C:\wings\sky.jpg C:\wings\pelican.jpg \ -compose differe
nce dif.jpg
composite.exe: unable to open image `\': No such file or directory @ error/blob.
c/OpenBlob/2674.
composite.exe: no decode delegate for this image format `' @ error/constitute.c/
ReadImage/501.
C:\Users\User>composite C:\Horizon_photos\PA160027.jpg C:\Horizon_photos\PA16002
8.jpg \ -compose difference dif.jpg
composite.exe: unable to open image `\': No such file or directory @ error/blob.
c/OpenBlob/2674.
composite.exe: no decode delegate for this image format `' @ error/constitute.c/
ReadImage/501.
C:\Users\User>convert C:\Horizon_photos\PA160027.jpg C:\Horizon_photos\PA160028.
jpg null: -poly '0.5,1, -0.5,1, 0.5,0'txt:
convert.exe: invalid argument for option `-poly': '0.5,1, @ error/convert.c/Conv
ertImageCommand/2344.
C:\Users\User>
Re: Subtracting two images
Posted: 2015-03-06T15:39:24-07:00
by snibgo
composite.exe: unable to open image `sky.jpg': No such file or directory
Have you got a file called "sky.jpg" in that directory? If so, then is it a real image?
Likewise pelican.jpg.
Code: Select all
C:\Users\User>composite sky.jpg pelican.jpg \ -compose differnce dif.jpg
I don't know what that backslash is doing.
The backslash is used for bash when one command is split across two lines. You are not using bash, nor is your command split across two lines.
Sadly, keywords like "difference" must be spelled correctly.
Re: Subtracting two images
Posted: 2015-03-06T19:50:41-07:00
by Deane
I am more interested in why the last 2 commands don't work as they are taken directly from the examples in the post above by Anthony.
Even better, just tell me how to subtract all pixels in "ImageB.jpg" from "ImageA.jpg" and put the result into "ImageC.jpg". I am not interested in the color, just the monochrome intensity values so that negative values display in black as if they were zero.
Thank you.
Re: Subtracting two images
Posted: 2015-03-06T20:15:13-07:00
by Deane
This works! (from
http://www.imagemagick.org/Usage/compare/#difference).
composite bag_frame1.gif bag_frame1.jpg -compose difference difference_jpeg.gif
Thanks for letting me know that those backslashes are from Bash and are not needed. They were confusing me.
Re: Subtracting two images
Posted: 2015-03-08T16:34:30-07:00
by anthony