Replace a color that doesn't match a list of colors

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
thekamz
Posts: 9
Joined: 2013-05-29T14:41:25-07:00
Authentication code: 6789

Replace a color that doesn't match a list of colors

Post by thekamz »

Hi all -

I'm working with an image segmentation program that requires that one type of object/region does be identified as "not of interest". The problem is that the resulting output is not usable for my project. For example: http://db.tt/qmb03ykI

Note that the thing marked "not of interest" was not coloured. What I need is something like this (made in GIMP): http://db.tt/4lVtZEt0

Since making that thing was tedious, and needs to be done for a lot of images, I was hoping there was some way to accomplish the same thing with IM.

Is it possible to tell IM to replace any colour in the image that doesn't match colour 1, colour 2, ..., colour N with some specified colour? For example, in the image above, if it didn't match pink (#D93E58) or violet (#4B01ED) then replace with blue (#0101CC).

Unless I'm missing something, I would still need to specify manually for each image which colours are "good" and which colour the "not good" ones should be replaced with, but even so that would save me a hell of a lot of time.

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

Re: Replace a color that doesn't match a list of colors

Post by snibgo »

There are many ways to approach this. Here is one.

Suppose your source image is src.png.

1. Make an image that contains the "good" colours. I'll just have three.

Code: Select all

convert xc:red xc:rgb(34,56,89) xc:green -append goodCols.png
2. Make a new version of the source, containing just the "good" colours.

Code: Select all

convert src.png +dither -remap goodCols.png srcMapped.png
srcMapped.png will now contain only "good" colours. All the pixels that were already good are unchanged. All the pixels that were bad will have changed.

3. Figure out the changed pixels.

Code: Select all

convert src.png srcMapped.png -compose Difference -composite -white-threshold 0 -negate diff.png
diff.png has white where the pixels weren't changed (they were good), black where they did change (they were bad).

4. Now I'll use diff.png as a mask to turn the bad pixels "Red".

Code: Select all

convert src.png ( +clone -fill Red -colorize 100 ) diff.png -compose Over -composite srcRedded.png
Once the system works, you could combine all the commands into one.

Caution: I made this up as I went along, so I may have made a mistake somewhere.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Replace a color that doesn't match a list of colors

Post by fmw42 »

Removed. snibgo's solution is better.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Replace a color that doesn't match a list of colors

Post by snibgo »

For my solution, I supposed that one of the "good" colours was red, but then changed all the bad pixels to red. Doh! Almost any other colour would have been better.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Replace a color that doesn't match a list of colors

Post by fmw42 »

Change all the colors you want to keep to transparent. Get the alpha channel and use as a mask with your image and create an image of the color you want to use for all the non-matching colors and composite using the mask.

convert image -fuzz XX% -fill none -opaque color1 tmpimage
convert tmpimage -fuzz XX% -fill none -opaque color2 tmpimage
...
convert tmpimage -fuzz XX% -fill none -opaque colorN tmpimage

convert image \( -clone 0 -fill othercolor -colorize 100% \) \( tmpimage -alpha extract \) -compose over -composite resultimage

If on Windows remove the \ before ( and ) and use %% instead of %

see
http://www.imagemagick.org/Usage/windows/
Last edited by fmw42 on 2013-06-01T17:16:46-07:00, edited 1 time in total.
thekamz
Posts: 9
Joined: 2013-05-29T14:41:25-07:00
Authentication code: 6789

Re: Replace a color that doesn't match a list of colors

Post by thekamz »

Thank you both very much for your help.

I have some issues (most likely I'm doing something wrong). In both cases I get an unexpected result after the final step.

fwm42: Assuming tempimage == tmpimage and othercolor is my "missing" colour, I get this after the final step: http://db.tt/BzdN4b2z

snibgo: Editing the last command a bit for Linux use - that is, add a \ before ( and ) and use 100% - I get this after the final step: http://db.tt/iFmZdm3n

In both cases, I'm good until the last step. Am I screwing something up?

For fwm42's suggestion, I used:

Code: Select all

convert berkeley-i12003.tif \( -clone 0 -fill "#0101CC" -colorize 100% \) \( tmpimage -alpha extract \) -compose over -composite resultimage.png

Where berkeley-i12003.tif is the "original" image that needs editing, resultimage.png is the output image, and #0101CC is the desired "missing" colour.

For snibgo's suggestion, I used:

Code: Select all

convert berkeley-i12003.tif \( +clone -fill "#0101CC" -colorize 100% \) diff.png -compose over -composite 12003Final.png
Where 12003Final.png is the output.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Replace a color that doesn't match a list of colors

Post by fmw42 »

My typos -- tempimage should have been tmpimage


You did not do all the steps to change colors that are close enough replacing them with none. Or do I misunderstand what you did.

Code: Select all

convert image -fuzz XX% -fill none -opaque color1 tmpimage
convert tempimage -fuzz XX% -fill none -opaque color2 tmpimage
...
convert tempimage -fuzz XX% -fill none -opaque colorN tmpimage
These have to be run first before doing the other steps. If this is the case, please show all steps so we can reproduce with the exact colors and fuzz values you used.
thekamz
Posts: 9
Joined: 2013-05-29T14:41:25-07:00
Authentication code: 6789

Re: Replace a color that doesn't match a list of colors

Post by thekamz »

fmw42 wrote:You did not do all the steps to change colors that are close enough replacing them with none. Or do I misunderstand what you did.

Code: Select all

convert image -fuzz XX% -fill none -opaque color1 tmpimage
convert tempimage -fuzz XX% -fill none -opaque color2 tmpimage
...
convert tempimage -fuzz XX% -fill none -opaque colorN tmpimage
These have to be run first before doing the other steps. If this is the case, please show all steps so we can reproduce with the exact colors and fuzz values you used.
My bad; I did these steps but wasn't clear about saying so. In my example, I had two "good" colours removed, resulting in this: http://db.tt/UBBiZECh
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Replace a color that doesn't match a list of colors

Post by fmw42 »

My bad; I did these steps but wasn't clear about saying so. In my example, I had two "good" colours removed, resulting in this: http://db.tt/UBBiZECh
You must have done something wrong, since this image has no transparency. What were your exact commands to create this image?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Replace a color that doesn't match a list of colors

Post by fmw42 »

why not just do something simple like replace anything not red with blue. exact colors measure from your image.

convert berkeley-i12003.tif -fuzz 20% -fill "rgb(75,1,237)" +opaque "rgb(217,62,88)" result.tif
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Replace a color that doesn't match a list of colors

Post by snibgo »

According to the documentation and in practise, "-colorize N" doesn't need a percent sign. Adding a percent sign seems harmless.

I did fluff my final command: the mask should be the negative of what I created, ie my "-negative" was wrong.

So this is what I get (Windows script):

Code: Select all

set IM=%IMG6858%

set SRC=berkeley-i12003.tif

%IM%convert xc:rgb(217,62,88) xc:rgb(75,1,237) -append goodCols.png

%IM%convert %SRC% +dither -remap goodCols.png srcMapped.png

%IM%convert berkeley-i12003.tif srcMapped.png -compose Difference -composite -white-threshold 0 diff.png

%IM%convert %SRC% ( +clone -fill Pink -colorize 100 ) diff.png -compose Over -composite srcRedded.png
We can combine the four converts, saving many reads and writes:

Code: Select all

%IM%convert ^
  xc:rgb(217,62,88) xc:rgb(75,1,237) -append -write mpr:goodCols +delete ^
  %SRC% ^
  ( +clone ^
    ( +clone +dither -remap mpr:goodCols ) ^
    -compose Difference -composite -white-threshold 0 ^
  ) ^
  ( +clone -fill Pink -colorize 100 ) ^
  +swap ^
  -compose Over -composite output.png
Note that this is faster but complex and harder to understand.
snibgo's IM pages: im.snibgo.com
thekamz
Posts: 9
Joined: 2013-05-29T14:41:25-07:00
Authentication code: 6789

Re: Replace a color that doesn't match a list of colors

Post by thekamz »

Thank you both once again.
snibgo wrote:According to the documentation and in practise, "-colorize N" doesn't need a percent sign. Adding a percent sign seems harmless.

I did fluff my final command: the mask should be the negative of what I created, ie my "-negative" was wrong.

So this is what I get (Windows script):

Code: Select all

set IM=%IMG6858%

set SRC=berkeley-i12003.tif

%IM%convert xc:rgb(217,62,88) xc:rgb(75,1,237) -append goodCols.png

%IM%convert %SRC% +dither -remap goodCols.png srcMapped.png

%IM%convert berkeley-i12003.tif srcMapped.png -compose Difference -composite -white-threshold 0 diff.png

%IM%convert %SRC% ( +clone -fill Pink -colorize 100 ) diff.png -compose Over -composite srcRedded.png
We can combine the four converts, saving many reads and writes:

Code: Select all

%IM%convert ^
  xc:rgb(217,62,88) xc:rgb(75,1,237) -append -write mpr:goodCols +delete ^
  %SRC% ^
  ( +clone ^
    ( +clone +dither -remap mpr:goodCols ) ^
    -compose Difference -composite -white-threshold 0 ^
  ) ^
  ( +clone -fill Pink -colorize 100 ) ^
  +swap ^
  -compose Over -composite output.png
Note that this is faster but complex and harder to understand.
fmw42 wrote:why not just do something simple like replace anything not red with blue. exact colors measure from your image.

convert berkeley-i12003.tif -fuzz 20% -fill "rgb(75,1,237)" +opaque "rgb(217,62,88)" result.tif
Both of these function as desired. This is great stuff!
Post Reply