Subtracting two images

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
WizardStan
Posts: 3
Joined: 2014-04-07T07:33:25-07:00
Authentication code: 6789

Subtracting two images

Post 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 Image
compare -compose difference black.bmp black.bmp black_diff.bmp
grey output Image
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.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Subtracting two images

Post 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
WizardStan
Posts: 3
Joined: 2014-04-07T07:33:25-07:00
Authentication code: 6789

Re: Subtracting two images

Post 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
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Subtracting two images

Post 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
WizardStan
Posts: 3
Joined: 2014-04-07T07:33:25-07:00
Authentication code: 6789

Re: Subtracting two images

Post by WizardStan »

ah, I see. Makes sense, makes sense.
Thanks a lot! I've got it all sorted out now.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Subtracting two images

Post 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!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Deane
Posts: 7
Joined: 2015-03-06T08:08:23-07:00
Authentication code: 6789

Re: Subtracting two images

Post 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. :(
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Subtracting two images

Post by snibgo »

Copy the text from the window, and paste it here.
snibgo's IM pages: im.snibgo.com
Deane
Posts: 7
Joined: 2015-03-06T08:08:23-07:00
Authentication code: 6789

Re: Subtracting two images

Post 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>
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Subtracting two images

Post 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.
snibgo's IM pages: im.snibgo.com
Deane
Posts: 7
Joined: 2015-03-06T08:08:23-07:00
Authentication code: 6789

Re: Subtracting two images

Post 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.
Deane
Posts: 7
Joined: 2015-03-06T08:08:23-07:00
Authentication code: 6789

Re: Subtracting two images

Post 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.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Subtracting two images

Post by anthony »

For Windows users see the notes...
http://www.imagemagick.org/Usage/windows/#dos
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply