Page 1 of 1

How do I use a colour to mask out pixels?

Posted: 2018-04-12T00:40:02-07:00
by dgpeters
I want to mask out (ie, blacken) any pixels that have any blue in them. This is not the same thing as removing blue pixels. I've tested dozens of commands but can't achieve that yet. I've spent hours in the documentation and searching with Google.

Actually that's how I'm trying to solve my problem. My real problem, and perhaps there's a more direct solution, is that I want yellow pixels to be white and anything that isn't yellow to be black. But I realize yellow is Red + Green (two channels). So the idea of using blue as a mask is how I think I might achieve that, but perhaps that's the wrong way. If there is a more direct way to isolate the yellow that would be better. By yellow I define that to mean the Red channel >90% and the Green channel is also >90%.

Thanks in advance.

$ convert -version
Version: ImageMagick 7.0.7-15 Q16 x86_64 2017-12-14 http://www.imagemagick.org
Copyright: © 1999-2018 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC HDRI
Delegates (built-in): bzlib freetype jng jpeg lcms png raw tiff webp xml zlib

Re: How do I use a colour to mask out pixels?

Posted: 2018-04-12T00:51:41-07:00
by dgpeters
Oh, and yellow must also have Blue <5%. I forgot that.

Re: How do I use a colour to mask out pixels?

Posted: 2018-04-12T01:41:07-07:00
by snibgo
dgpeters wrote:I want yellow pixels to be white and anything that isn't yellow to be black.
A common way is (Windows BAT syntax):

Code: Select all

magick ^
  in.png ^
  -fuzz 10%% ^
  -fill black +opaque Yellow ^
  -fuzz 0 ^
  -fill White +opaque Black ^
  out.png
This turns everything that isn't yellow into black, and then all not-black is turned white. The first fuzz includes as "yellow" any pixels within 10% of that colour. The second fuzz restores the default setting of fuzz zero, so only pixels that are exactly black remain black.
dgpeters wrote:By yellow I define that to mean the Red channel >90% and the Green channel is also >90%.
And, I assume, the Blue channel can be anything?

I would do that as a colour separation:

Code: Select all

magick ^
  in.png ^
  -channel RG -separate +channel ^
  -threshold 90%% ^
  -compose Darken -composite ^
  out.png
"-channel RG -separate +channel" makes two greyscale images from just the R and G channels. "-threshold" operates on both those images. Then we combine them, takes the darkest of each.

The result is white where input red > 90% and green > 90%, otherwise it is black.

... And then you snuck in the blue requirement, ha! We can threshold the blue channel at 5%, then negate is so the result is white only where B < 5%. Then it gets a bit complicated.

Code: Select all

magick ^
  in.png ^
  ( -clone 0 ^
    -channel RG -separate +channel ^
    -threshold 90%% ^
  ) ^
  ( -clone 0 ^
    -channel B -separate +channel ^
    -threshold 5%% ^
    -negate ^
  ) ^
  -background None ^
  -compose Darken -layers Merge ^
  out.png

Re: How do I use a colour to mask out pixels?

Posted: 2018-04-12T12:43:13-07:00
by dgpeters
Here's how I translated that for macOS:
magick qq.tiff \( -clone 0 -channel RG -separate +channel -threshold 90% \) \( -clone 0 -channel B -separate +channel -threshold 5% -negate \) -background None -compose Darken -layers Merge qq2.tiff
I was getting all black output, but I trusted you, so I played with the percentages until it started to work. Here's what gave me fairly good preliminary results:
magick qq.tiff \( -clone 0 -channel RG -separate +channel -threshold 40% \) \( -clone 0 -channel B -separate +channel -threshold 55% -negate \) -background None -compose Darken -layers Merge qq2.tiff
I will have to study these results and do some more tinkering with the percentages. It's not bad. I hope someone considers making this into a parameter for ImageMagick, something like this: (this would blacken all pixels when the Y channel is below 90%.)
magick qq.tiff -channel Y -maskout 90%

Re: How do I use a colour to mask out pixels?

Posted: 2018-04-12T12:57:01-07:00
by dgpeters
I just realized my proposed ImageMagick parameter doesn't do exactly what I want, but you get the idea.

Re: How do I use a colour to mask out pixels?

Posted: 2018-04-12T17:14:29-07:00
by snibgo
"channel Y" already has a meaning, as a channel of CMY or CMYK images. Using this channel might give the effect you want.