2

I am currently working on a program that can detect if a red object is kept in my room or is is there a blue object. The rest of my surroundings is either white or black. I have tried to minimize the variation of light in my room.

I have successfully created a mask around the object given a certain hue range. I want my program to print for me :

1) "Red"- If there is a red object

2) "Blue"- If there is a blue object

I don't know how to proceed. Following is my program that cretes the mask around the object that is blue. I have given the hue range of a few other colours also. So that you can try it.

The program:

import cv2
import numpy as np

cam = cv2.VideoCapture(1)

while True:
    _, frame = cam.read()

    denoised = cv2.GaussianBlur(frame, (31, 31), 35)
    hsv = cv2.cvtColor(denoised, cv2.COLOR_BGR2HSV)


    lower_blue = np.array([110, 50, 50])
    upper_blue = np.array([160, 255, 255])

    mask = cv2.inRange(hsv, lower_red, upper_red)
    res = cv2.bitwise_and(frame, frame, mask=mask)

    cv2.imshow('frame', frame)
    #cv2.imshow('mask', mask)
    cv2.imshow('res', res)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cam.release()
cv2.destroyAllWindows()

Hue of different colours (I am not sure about the hue of red because it doesn't work for some colours- I have tried a few solutions from Stackoverflow):

lower_red = np.array([0, 100, 100])
upper_red = np.array([0, 255, 255])

lower_yellow = np.array([15, 210, 20])
upper_yellow = np.array([35, 255, 255])

lower_green = np.array([29, 86, 6])
upper_green = np.array([64, 255, 2555])

lower_orange = np.array([10, 100, 20])
upper_orange = np.array([20,255,255])

Following are some sample images that you can experiment with:

Blue Image

Red Image

enter image description here

1 Answer 1

3

Your approach is correct in a way. But to determine the color of a specific region of the image, you need to calculate the Euclidean distance between the known dataset of the colors and the L*a*b averages of the region.

  1. Detect a specific region of interest, for which you need the color.
  2. Refer the following code to determine the color within the region of interest.

    class ColorLabeler:
        def __init__(self):
            # initialize the colors dictionary, containing the color
            # name as the key and the RGB tuple as the value
            colors = OrderedDict({
                "red": (255, 0, 0),
                "green": (0, 255, 0),
                "blue": (0, 0, 255)})
    
            # allocate memory for the L*a*b* image, then initialize
            # the color names list
            self.lab = np.zeros((len(colors), 1, 3), dtype="uint8")
            self.colorNames = []
    
            # loop over the colors dictionary
            for (i, (name, rgb)) in enumerate(colors.items()):
                # update the L*a*b* array and the color names list
                self.lab[i] = rgb
                self.colorNames.append(name)
    
            # convert the L*a*b* array from the RGB color space
            # to L*a*b*
            self.lab = cv2.cvtColor(self.lab, cv2.COLOR_RGB2LAB)
    
    def label(self, image, c):
        # construct a mask for the contour, then compute the
        # average L*a*b* value for the masked region
        mask = np.zeros(image.shape[:2], dtype="uint8")
        cv2.drawContours(mask, [c], -1, 255, -1)
        mask = cv2.erode(mask, None, iterations=2)
        mean = cv2.mean(image, mask=mask)[:3]
    
        # initialize the minimum distance found thus far
        minDist = (np.inf, None)
    
        # loop over the known L*a*b* color values
        for (i, row) in enumerate(self.lab):
            # compute the distance between the current L*a*b*
            # color value and the mean of the image
            d = dist.euclidean(row[0], mean)
    
            # if the distance is smaller than the current distance,
            # then update the bookkeeping variable
            if d < minDist[0]:
                minDist = (d, i)
    
        # return the name of the color with the smallest distance
        return self.colorNames[minDist[1]]
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.