Replace colors conditionally by comparing 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
Halley
Posts: 2
Joined: 2020-01-25T09:09:37-07:00
Authentication code: 1152

Replace colors conditionally by comparing two images?

Post by Halley »

I want to compare two images, to compose image B onto image A but at the same time replacing the colors where each image has colored pixels. I also want to change the color conditionally with some kind of defined palette.

Image A
Image

Image B
Image

What I want to do is if the cyan (0,255,255) in img A matches where the blue is in img B (0,0,255) I want it to be replaced with (255,128,128) and if the pink (255,0,255) matches where the blue is in img B (0,0,255) I want it to be replaced with (128,128,255).

Like so:
Image

Windows 10 | ImageMagick 7.0.9-17

Any help would be greatly appreciated!

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

Re: Replace colors by comparing two images with a defined palette?

Post by snibgo »

Yes, it is possible. Begin by breaking the problem into sub-problems. Do you now how to change one colour into another? How to change (0,255,255) into (255,128,128)?
snibgo's IM pages: im.snibgo.com

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

Re: Replace colors conditionally by comparing two images?

Post by fmw42 »

Here is one way to do it.

1) Replace the cyan and magenta in A.png with your new colors
2) Create a white/black mask for your B.png
3) Make white into transparent in A.png and then composite that over B.png
4) Use the mask to composite the new colored A.png over the previous composite to make the result

Code: Select all

convert A.png -alpha off -fuzz 1% -fill "rgb(255,128,128)" -opaque cyan -fill "rgb(128,128,255)" -opaque magenta A_recolored.png
convert B.png -alpha off -fuzz 1% -fill black +opaque blue -fill white -opaque blue B_mask.png
convert B.png \( A.png -alpha set -transparent white \) -compose over -composite BA_compose.png
convert BA_compose.png A_recolored.png B_mask.png -compose over -composite result.png

Here are these commands combined into one command line:

Unix Syntax:

Code: Select all

convert \
A.png -alpha off -write mpr:A +delete \
B.png -alpha off -write mpr:B +delete \
\( mpr:B \( mpr:A -transparent white \) -compose over -composite \) \
\( mpr:A -fuzz 1% -fill "rgb(255,128,128)" -opaque cyan -fill "rgb(128,128,255)" -opaque magenta \) \
\( mpr:B -fuzz 1% -fill black +opaque blue -fill white -opaque blue \) \
-compose over -composite result2.png
Windows Syntax:

Code: Select all

convert ^
A.png -alpha off -write mpr:A +delete ^
B.png -alpha off -write mpr:B +delete ^
( mpr:B ( mpr:A -transparent white ) -compose over -composite ) ^
( mpr:A -fuzz 1% -fill "rgb(255,128,128)" -opaque cyan -fill "rgb(128,128,255)" -opaque magenta ) ^
( mpr:B -fuzz 1% -fill black +opaque blue -fill white -opaque blue ) ^
-compose over -composite result2.png

Halley
Posts: 2
Joined: 2020-01-25T09:09:37-07:00
Authentication code: 1152

Re: Replace colors conditionally by comparing two images?

Post by Halley »

Wow that's amazing, it worked! Thank you! I did manage to replace colors but clipping out the mask had be stumped, I have much to learn. :D

The first command works perfectly, the second seems to introduce some artefacts and misses out the transparency, I still need to study the command, but they look the same to me. :shock:

Code: Select all

convert A.png -alpha off -fuzz 1% -fill "rgb(255,128,128)" -opaque cyan -fill "rgb(128,128,255)" -opaque magenta A_recolored.png
convert B.png -alpha off -fuzz 1% -fill black +opaque blue -fill white -opaque blue B_mask.png
convert B.png \( A.png -alpha set -transparent white \) -compose over -composite BA_compose.png
convert BA_compose.png A_recolored.png B_mask.png -compose over -composite result.png
Image

Code: Select all

convert ^
A.png -alpha off -write mpr:A +delete ^
B.png -alpha off -write mpr:B +delete ^
( mpr:B ( mpr:A -transparent white ) -compose over -composite ) ^
( mpr:A -fuzz 1% -fill "rgb(255,128,128)" -opaque cyan -fill "rgb(128,128,255)" -opaque magenta ) ^
( mpr:B -fuzz 1% -fill black +opaque blue -fill white -opaque blue ) ^
-compose over -composite result2.png
Image

Thank you again!

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

Re: Replace colors conditionally by comparing two images?

Post by fmw42 »

try increasing the -fuzz from 1% to say 5% or higher. Not sure why it should not be the same. I tested the unix version and it works fine for me.

Note if you are putting the code in a .bat file, then you need to make some changes. % goes to %%.

Post Reply