Magick Convert Evaluate Sequence OR Color on Mismatched Pixels

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Post Reply
troynguyen8
Posts: 7
Joined: 2018-10-14T18:51:53-07:00
Authentication code: 1152

Magick Convert Evaluate Sequence OR Color on Mismatched Pixels

Post by troynguyen8 » 2018-10-14T20:37:55-07:00

Hey all, right now I'm running

Code: Select all

magick convert -colorspace RGB img1.jpg img2.jpg -evaluate-sequence OR result.jpg
to output a new image at

Code: Select all

result.jpg
that only contains pixels present in both

Code: Select all

img1.jpg
and

Code: Select all

img2.jpg
However, for any pixels that aren't present in both img1.jpg and img2.jpg, the converted image has a white pixel in that spot.

Below is an example of what I'm talking about:
Image

Is there anyway to make the differing pixels have a different color besides white?

snibgo
Posts: 11788
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Magick Convert Evaluate Sequence OR Color on Mismatched Pixels

Post by snibgo » 2018-10-15T03:15:42-07:00

Please tell us what version of IM, on what platform. Also post the actual input and output files, not some mashup.
troynguyen8 wrote:... pixels that aren't present in both img1.jpg and img2.jpg ...
That doesn't make sense.

"-evaluate-sequence Or" will make output pixel values that are the binary "Or" of two or more inputs. For example, with binary inputs "10001111" and "00111111" the output will be "10111111".

Another example: inputs "10001111" and "10000000", the output will be "10001111", the same as the first input.

Hence the output will be no darker than either input, but not necessarily white. "Or" isn't a difference operation.

What effect are you trying to get?
snibgo's IM pages: im.snibgo.com

troynguyen8
Posts: 7
Joined: 2018-10-14T18:51:53-07:00
Authentication code: 1152

Re: Magick Convert Evaluate Sequence OR Color on Mismatched Pixels

Post by troynguyen8 » 2018-10-15T09:41:42-07:00

My apologies, this is my first time posting:

IM Version: 7.0.8-12 Q16 x64
Platform: Windows

Input1 File:Image
Input2 File:Image

Output File: Image

The desired effect I'm trying to get is a result image that only has the pixels present in all inputs. So if I fed img1, img2, img3, and img4 into the above command I was running, the output file would have an image with only the pixels found in every image, and the pixels that conflicted would be of another color, such as pink.

The output file I was given above was as a result of running "-evaluate-sequence OR". I too thought that the desired evaluate sequence to get the effect I wanted was "AND", but using AND gave me an image with every pixel of all images stacked on top of one another (perhaps AND and OR are mixed up?)

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

Re: Magick Convert Evaluate Sequence OR Color on Mismatched Pixels

Post by fmw42 » 2018-10-15T10:04:59-07:00

What you want is to do a difference and use that as a mask image to either make the difference transparent or red, for example.

Code: Select all

convert image1.jpg \
\( -clone 0 image2.jpg -compose difference -composite -threshold 10% -negate \) \
-compose copy_opacity -composite \
result.png
Image

Code: Select all

convert image1.jpg \
\( -clone 0 image2.jpg -compose difference -composite -threshold 10% -negate \) \
-compose copy_opacity -composite \
-background red -compose over -flatten \
result2.png
Image

Note that you could have used compare also to show only where they are different. But JPG is lossy and the two images won't be identical even where they look the same due to JPG compression. So that is why I had to threshold above and have to use -fuzz below.

Code: Select all

compare -fuzz 15% -metric rmse image1.jpg image2.jpg diff.png
Image

The red shows the difference and the rest of the image is subdued in contrast simply to show the image, but if it is not red, then it means the two are the same (within the fuzz value).

troynguyen8
Posts: 7
Joined: 2018-10-14T18:51:53-07:00
Authentication code: 1152

Re: Magick Convert Evaluate Sequence OR Color on Mismatched Pixels

Post by troynguyen8 » 2018-10-15T10:21:21-07:00

fmw42 wrote:
2018-10-15T10:04:59-07:00
What you want is to do a difference and use that as a mask image to either make the difference transparent or red, for example.

Code: Select all

convert image1.jpg \
\( -clone 0 image2.jpg -compose difference -composite -threshold 10% -negate \) \
-compose copy_opacity -composite \
result.png
Image

Code: Select all

convert image1.jpg \
\( -clone 0 image2.jpg -compose difference -composite -threshold 10% -negate \) \
-compose copy_opacity -composite \
-background red -compose over -flatten \
result2.png
Image

Note that you could have used compare also to show only where they are different. But JPG is lossy and the two images won't be identical even where they look the same due to JPG compression. So that is why I had to threshold above and have to use -fuzz below.

Code: Select all

compare -fuzz 15% -metric rmse image1.jpg image2.jpg diff.png
Image

The red shows the difference and the rest of the image is subdued in contrast simply to show the image, but if it is not red, then it means the two are the same (within the fuzz value).
Thanks for the quick reply, Fred.

Is there any way you could do a quick explanation of what your second convert script is doing? That's pretty similar to what I want to do. If not, that's understandable and I can dissect the pieces myself.

Another question: Could that convert script support more than two inputs? Or is the -compose difference limited to one image compared to one other?

Ultimately, I want to build a script that will accept ~1000 images (in batches), and create a "template" image that contains only the pixels present in all images, except where there was variance between the images a color would be displayed such as red below. After this template is obtained, I want to check if another input image contains at least all the pixels present in the template, including white pixels.

I apologize if my posts have been unclear, English isn't my first language and I'm new to IM!

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

Re: Magick Convert Evaluate Sequence OR Color on Mismatched Pixels

Post by fmw42 » 2018-10-15T10:39:40-07:00

Line1: read image1
Line2: copy image1 and read image2 and get the difference, threshold at 10% to make binary and avoid JPG compression difference and negate (invert black vs white)
Line3: put the binary image into the alpha channel to make the differences transparent
Line4: set the background to red, make the compose setting to over, since it affects the flatten operator and flatten the result agains the the background so that transparent becomes red
Line5: write the output

Code: Select all

convert image1.jpg \
\( -clone 0 image2.jpg -compose difference -composite -threshold 10% -negate \) \
-compose copy_opacity -composite \
-background red -compose over -flatten \
result2.png
-composite only takes two images at a time.

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

Re: Magick Convert Evaluate Sequence OR Color on Mismatched Pixels

Post by fmw42 » 2018-10-15T10:59:01-07:00

Post 4 or 5 or 6 images that you want to compare. I will try to write a script that will compare them sequentially and keep adding to the difference mask.

troynguyen8
Posts: 7
Joined: 2018-10-14T18:51:53-07:00
Authentication code: 1152

Re: Magick Convert Evaluate Sequence OR Color on Mismatched Pixels

Post by troynguyen8 » 2018-10-15T11:32:57-07:00

fmw42 wrote:
2018-10-15T10:59:01-07:00
Post 4 or 5 or 6 images that you want to compare. I will try to write a script that will compare them sequentially and keep adding to the difference mask.
Hey Fred, thanks again for the tremendous help. I could definitely try to figure it out myself! If you're still compelled to write such a script, I made an imgur album with 5 pictures you could try on:

https://imgur.com/a/DniVPE5

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

Re: Magick Convert Evaluate Sequence OR Color on Mismatched Pixels

Post by fmw42 » 2018-10-15T12:15:54-07:00

This will loop over each image and compare to the first saving the difference as black in a white image. It multiplies each difference with the previous to note all the successive differences as more black and saves the result as mask.png. Then after the loop is done I use the mask to write red where the mask was black onto the first image.

Unix bash script:

Code: Select all

cd
cd desktop/test
arr=(`ls`)
num=${#arr[*]}
convert "${arr[0]}" -fill white -colorize 100 mask.png
for ((i=1; i<num; i++)); do
convert "${arr[0]}" "${arr[$i]}" -compose difference -composite -threshold 10% -negate mask.png -compose multiply -composite mask.png
done
convert "${arr[0]}" \( +clone -fill red -colorize 100 \) \( mask.png -negate \) -compose over -composite result.png
cd
Mask:
Image


Result:
Image

troynguyen8
Posts: 7
Joined: 2018-10-14T18:51:53-07:00
Authentication code: 1152

Re: Magick Convert Evaluate Sequence OR Color on Mismatched Pixels

Post by troynguyen8 » 2018-10-15T12:20:57-07:00

fmw42 wrote:
2018-10-15T12:15:54-07:00
This will loop over each image and compare to the first saving the difference as black in a white image. It multiplies each difference with the previous to note all the successive differences as more black and saves the result as mask.png. Then after the loop is done I use the mask to write red where the mask was black onto the first image.

Unix bash script:

Code: Select all

cd
cd desktop/test
arr=(`ls`)
num=${#arr[*]}
convert "${arr[0]}" -fill white -colorize 100 mask.png
for ((i=1; i<num; i++)); do
convert "${arr[0]}" "${arr[$i]}" -compose difference -composite -threshold 10% -negate mask.png -compose multiply -composite mask.png
done
convert "${arr[0]}" \( +clone -fill red -colorize 100 \) \( mask.png -negate \) -compose over -composite result.png
cd
Mask:
Image


Result:
Image
That's seriously amazing. Thank you so much!!!

Post Reply