Page 1 of 1
Negate (Invert) only specific channel?
Posted: 2013-12-05T13:10:58-07:00
by imek
Related to my question question about
negating only non-saturated colors, I would like to know how to convert a specific [s]channel[/s] color (say blue) to grayscale.
I tried to do it with a mask, but the
b I used instead of
g in the -channel option doesn't seem to refer to the
blue channel.
Code: Select all
convert img.png -colorspace HSB -channel b -separate +channel -threshold 0% mask
Re: Negate (Invert) only specific channel?
Posted: 2013-12-05T13:20:21-07:00
by fmw42
I am not sure what you really want. If you want channel b to be gray, all that does is make that channel a constant value and I suspect is not what you want.
Nevertheless taking your question literally, here is how to make the blue channel gray and leave the other channels the same.
convert image -channel b -evaluate set 50% +channel result
If you really want all blue shades to be gray, then you need to find what hue is blue and create a mask for that and then do the same as before. So you would be processing the hue channel from HSB which is the red channel and thresholding to get only values near blue to white and all the rest to black. Blue is at hue=240 so that needs to be converted to range 0 to 100% so hue=100*240/360=66.7%
so the mask would be obtained by
convert image -colorspace HSB -channel r -fuzz XX% -fill black +opaque "gray(67%)" -fill white -opaque "gray(67%)" +channel mask
Re: Negate (Invert) only specific channel?
Posted: 2013-12-05T13:30:14-07:00
by imek
You're right: what I really want is to replace shades of blue with shades of gray.
Can the mask be non-monotone? I'd like to preserve the shades brightness, so alpha is a must.
From this, to That:
Re: Negate (Invert) only specific channel?
Posted: 2013-12-05T14:00:24-07:00
by fmw42
try this
convert neg-bw-b1.png \
\( -clone 0 -colorspace HSL -channel b -separate +channel \) \
\( -clone 0 -colorspace HSL -channel r -separate +channel -fuzz 10% -fill black +opaque "gray(67%)" -fill white -opaque "gray(67%)" \) \
-compose over -composite result1.png
or
convert neg-bw-b1.png \
\( -clone 0 -colorspace HSL -channel b -separate +channel -auto-level \) \
\( -clone 0 -colorspace HSL -channel r -separate +channel -fuzz 10% -fill black +opaque "gray(67%)" -fill white -opaque "gray(67%)" \) \
-compose over -composite result2.png
Re: Negate (Invert) only specific channel?
Posted: 2013-12-05T14:07:17-07:00
by imek
Hmm.. Both fail to preserve the colors behind the blue section and turn them to complete grayscale. Pure blue (#0000FF) should be completely grayscale, but colors such as purple or cyan should lose their saturation only partially, proportionally to their "blue-ness". I hope this makes sense.
Re: Negate (Invert) only specific channel?
Posted: 2013-12-05T15:25:19-07:00
by fmw42
try this
convert neg-bw-b1.png \
\( -clone 0 -colorspace HSL -channel b -separate +channel -auto-level \) \
\( -clone 0 -colorspace HSL -channel g -separate +channel -auto-level \) \
\( -clone 0 -colorspace HSL -channel r -separate +channel -fuzz 10% -fill black +opaque "gray(67%)" -fill white -opaque "gray(67%)" \) \
\( -clone 2 -clone 3 -compose multiply -composite \) \
-delete 2,3 -compose over -composite result.png
Re: Negate (Invert) only specific channel?
Posted: 2013-12-05T20:44:40-07:00
by imek
Great! Thank you.