Page 1 of 2

Finding the difference of black and transparent images

Posted: 2016-09-05T10:56:06-07:00
by obto
I am trying to find the difference between images that are only black and transparent.

Since compose difference is just abs(src - dest), using threshold 0 to generate a "difference mask" fails.

Code: Select all

convert current-frame.png -compose difference -composite -threshold 0 difference-mask.png
Is there a way to get the desired output (below) without using the compare command?

Previous Frame:
Image

Current Frame:
Image

Desired Output:
Image

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T11:00:36-07:00
by snibgo

Code: Select all

convert current-frame.png previous-frame.png -alpha extract -compose Difference -composite d.png

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T11:22:42-07:00
by obto
Ah that works perfectly, thanks.

I forgot to mention in my original post, though, that these images don't have to be 100% black; that was just an edge case I found. Do you have a solution for a case like this?:

Previous:
Image

Current:
Image

Desired Output:
Image

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T11:44:15-07:00
by snibgo
In your OP, I guessed the result you wanted was: black where the transparency was the same, otherwise white.

What result do you want when the inputs have colour as well as transprency?

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T12:28:01-07:00
by obto
I'd want exactly like the above. Wherever anything is different: white, otherwise black.

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T12:53:19-07:00
by snibgo
oboto wrote:Wherever anything is different: white, otherwise black.
But that's not your "desired output" image.

Wherever everything is different: white, otherwise black:

Code: Select all

convert ^
  current-frame.png ^
  previous-frame.png ^
  ( -clone 0-1 -alpha extract -compose Difference -composite ) ^
  ( -clone 0-1 -alpha off -compose Difference -composite ) ^
  -delete 0-1 ^
  -compose Darken -composite ^
  de.png
Wherever anything is different: white, otherwise black:

Code: Select all

convert ^
  current-frame.png ^
  previous-frame.png ^
  ( -clone 0-1 -alpha extract ^
    -compose Difference -composite ) ^
  ( -clone 0-1 -alpha off -fill White +opaque Black ^
    -compose Difference -composite ) ^
  -delete 0-1 ^
  -compose Lighten -composite ^
  da.png
Windows BAT syntax, adjust for other shells.

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T13:38:36-07:00
by obto
Let me clarify what i mean by anything. If i was given current-frame.png and asked to circle any pixels that have changed since previous-frame.png, that is what the output would be.

I was basically looking for a way to emulate the compare command with convert in order to avoid writing a temporary image to disk before further processing.

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T13:44:35-07:00
by snibgo
My "everything" is different means "the colour is different AND the alpha is different".

My "anything" is different means "the colour is different OR the alpha is different".

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T13:54:06-07:00
by fmw42
This seems to come close, though I do not know if it is a universal solution.

Code: Select all

convert previous-frame.png current-frame.png -channel rgba -compose difference -composite -alpha off +channel -threshold 0 result.png

EDIT: I do not believe this is a proper solution. See my subsequent post below.

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T14:19:44-07:00
by obto
Yeah, that is really close to perfect. The regions are slightly off but this should be fine. Think ill run with this.

Thank you both very much :)

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T15:00:26-07:00
by fmw42
Try my solution on other images before you settle it. I am not sure if -channel rgba is really letting -compose difference deal properly with the alpha channel.

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T18:10:14-07:00
by fmw42
I do not think my solution above is correct. I think the following may be a better approach.

Code: Select all

convert previous-frame.png current-frame.png -channel rgba -compose difference -composite -separate +channel -evaluate-sequence sum result.png

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T18:37:33-07:00
by obto
Spent a bit of time to make a test image (below) and it looks like your most recent script does just as well as compare does. I just have to add threshold 0 at the very end for my own use-case since i end up multiplying this mask later on.

Would you mind explaining why it works, though?

Thanks so much :)

Previous:
Image

Current:
Image

Desired Result:
Image

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T18:51:45-07:00
by fmw42
Turning on -channel rgba, I believe makes -compose difference also include the alpha channel. So you now have 4 independently computed difference channels. To get all the differences combined together (depending upon which approach you use as per snibgo's comments), I combine the images together by adding them all together. That means if all 4 channels are black (the same), you get black, but if any channel is not black (they are not the same), you get white. In IM 6 non-hdri, adding white to white produces white. That is values are clipped at white and no overflow or wrap around.

Yes, you should add -threshold 0 at the end, since you may have images that do not have exactly the same colors. Thus you might get a sum that is not fully white, because the two channels were close in color, but not the same. Thus the difference would fall between black and white.

Note that -compose difference is the absolute value of the subtraction of one image with another. It will never be negative. Any negative value from the subtraction is negated so that the result is positive.

Re: Finding the difference of black and transparent images

Posted: 2016-09-05T19:16:26-07:00
by obto
Ah so it looks like the main reason i was struggling was because i thought -compose difference would also diff the alpha channel. Looks like magick by default only uses rgb for its operators unless told (default setting is: RGBK,sync)

Quick question: Why is it necessary to reset the channel settings before adding all the images together?