Search code examples
pythonnumpycolorsgrayscale

Numpy for specific color section extraction


I'm pretty new to python and trying to separate colored sections in an image from the grayscaled. Although this code (see below) gets me the results I'm looking for, it takes way to long (10+ seconds on normal images).

I looked for one hour and didn't find an appropriate answer, as most just separate specific colors (black, white, ...) or thresholds.

As far as I (already) know numpy is the way to go, but I was not successful :S

Looking forward for help - Thanks!!

    gray_elements = np.zeros_like(image)
    gray_elements[:] = 255

    colored_segments = np.zeros_like(image)
    colored_segments[:] = 255
    
    # Separate black-to-white-colors from colored
    for y in range(image.shape[0]):
        for x in range(image.shape[1]):

            pxl = image[y, x]
            if max(pxl) - min(pxl) > 5:
                colored_segments[y, x] = pxl
            else:
                gray_elements[y, x] = pxl

Solution

  • Untested, but as it's St Patrick's Day...

    If you have a Numpy array na containing a 3-channel RGB image, it will have na.shape of (h,w,3).

    You can get the maximum of the 3 channels at each point with:

    ma = np.amax(na, axis=2, keepdims=True)
    

    and the minimum with:

    mi = np.amin(na, axis=2, keepdims=True)
    

    then the difference with:

    diff = ma - mi
    

    Then make a Boolean (true/false) mask with:

    grey = diff < 5
    

    If/when you become more familiar with Numpy, you'd probably use the peak-to-peak function.


    Normally though, you would use OpenCV, to convert to HSL colourspace and then find pixels where the Saturation channel is low, meaning the colour is unsaturated and rather grey.