Check if a pixel (RGB or HSV) is contained in a color scale range, how

2.3k views Asked by At

I need to check if a pixel (RGB) is contained in the color scale ranging from very light pink to dark purple. Using the RGB scheme can I do a check like this:

IF image [x, y] [R]> threshold and image [x, y] [G]> threshold image [x, y] [B]> threshold and \
     image [x, y] [R] <threshold and image [x, y] [G] < threshold image [x, y] [B] <threshold THAN ...

?

If not, I also have available the option of having the pixel in HSV.

Thanks!

3

There are 3 answers

0
Ned Batchelder On

You probably want to work in HSV, because it maps much more intuitively to human perception than RGB. If you get a human to mark colors as "in range" or "out of range", and map them in HSV, you'll be able to find a bound on the H, S, and V values that indicates in and out.

Then you can use a simple range check like you've outlined about to determine if a color is in or out. If you need Python help with the color space conversions, the standard library module colorsys will do it for you.

3
tkerwin On

If you're talking about integer RGB values, you can put all of the values into a set and then simply do if color in set:

If your 'color range' is defined in a complex way, defining a concrete set of colors might be the only way.

0
Hugh Bothwell On

Using per-channel cut-off values is equivalent to designating an axis-aligned rectangular box in RGB color space. A box is kind of a nasty shape - you will likely have to include some areas you don't really want (in the corners) to avoid excluding areas you do want (in the center of the faces).

If you instead choose two anchor points and a cut-off distance, it is the equivalent of an arbitrarily aligned 3d ellipsoid - which should hopefully more accurately match the colors you want.

Something like

def colorRange(ax, ay, az, bx, by, bz, dist):
    def testPixel(cx, cy, cz):
        return (
            (cx-ax)**2 + (cy-ay)**2 + (cz-az)**2
            + (cx-bx)**2 + (cy-by)**2 + (cz-bz)**2
        ) < dist**2
    return testPixel

isPurple = colorRange(140,0,140, 255,75,255, 230)
isPurple(203,46,195)  # -> True