-1

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 ?

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
  • Your color_to_seek needs to be a tuple, but you define it as a list. You are comparing it to a tuple so it can never be equal. – Crapicus Sep 09 '22 at 14:12
  • @Crapicus. Nothing happened if i changes its type – Sharif Bhatti Sep 09 '22 at 14:16
  • It is most definitely a bug though. There may be more. FYI (1, 2, 3) is not equal to [1, 2, 3] is my point. And that's also why I added it as a comment not an answer. Cheers. – Crapicus Sep 09 '22 at 14:17
  • you are expecting to find __that exact color__ in a _photo_, which always has some noise (and compression artefacts). why? why do you not look for a **range of colors**? – Christoph Rackwitz Sep 09 '22 at 16:23
  • @ChristophRackwitz If there is any answer which you think will be fine kindly share it. I didn't tried this solution. – Sharif Bhatti Sep 10 '22 at 08:41
  • use OpenCV's `inRange`, maybe combine with cvtColor to HSV or HSL space – Christoph Rackwitz Sep 10 '22 at 10:32
  • original = cv2.cvtColor(origina, cv2.COLOR_BGR2HSV) Then do upper and lower for yellow. then do inrange. then so mask for black or white – toyota Supra Sep 10 '22 at 12:08
  • original = cv2.imread('image.png') # Convert Image to Image HSV original = cv2.cvtColor(original, cv2.COLOR_BGR2HSV) # Defining lower and upper bound HSV yellow values. ? denote to specified yellow. lower = np.array([?, ?, ?]) upper = np.array([?, ?, ?]) # Defining mask for detecting color mask = cv2.inRange(hsv, lower, upper) – toyota Supra Sep 10 '22 at 12:11
  • Another thing is... original[x,y]=[220, 211, 81] Or Change to black img[?:?,?:?] = (0,0,0) ? denote specified coordinate of x and y. – toyota Supra Sep 10 '22 at 12:14
  • 1
    You have a cyan mask, not a yellow one! – fmw42 Sep 11 '22 at 22:57

1 Answers1

0

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)
u1234x1234
  • 2,062
  • 1
  • 1
  • 8