pythonopencvimage-processingbinary-image

How to find pixel color in image?


I am trying to make the black and white mask. Below image has mask of yellow color of chair. I am making it to white and else everything as black. I have used this color [220, 211, 81] for a mask. If i am finding this pixel color it shows that there is nothing like this. What am i doing wrong ? Code:

import cv2

color_to_seek = [220, 211, 81]
original = cv2.imread('image.png')
original = cv2.cvtColor(original, cv2.COLOR_BGR2RGB)

amount = 0
for x in range(original.shape[0]):
    for y in range(original.shape[1]):
        r, g, b = original[x, y]
        if (r, g, b) == color_to_seek:
            amount += 1

print(amount)`

Image: Image

I am expecting that yellow mask should replaced by white pixels and everything as black. Is there a difference between mask or pixel color ?. Elaborate little bit ?


Solution

  • As pointed by Christoph Rackwitz using the exact color value may be not the best way for the mask extraction.

    Using ranges for color comparisons and using color space that has separate luminance and color channels (HSV or LAB for example) could improve results:

    enter image description here

    You may need to find thresholds that have an acceptable number of false positives/false negatives for your specific application.

    Example:

    import cv2
    import numpy as np
    
    image = cv2.imread('room.png')
    
    color_to_seek_rgb = np.array([142, 140, 60])
    color_to_seek_hsv = cv2.cvtColor(color_to_seek_rgb.reshape(1, 1, 3).astype(np.uint8), cv2.COLOR_BGR2HSV).flatten()
    
    image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    # using lower values for H channel as it encodes luminance not a color information
    lower_bound = color_to_seek_hsv - [10, 20, 20]
    upper_bound = color_to_seek_hsv + [10, 20, 20]
    mask = cv2.inRange(image_hsv, lower_bound, upper_bound)
    
    cv2.imwrite("mask.jpg", mask)