Below is my python code for tracking white color objects.
It works - but only for a few seconds and then the whole screen turns black and in some times it not work.
I experimented with blue color and it works - but white and green are giving me problems:
import cv2 import numpy as np cap = cv2.VideoCapture(0) while(1): _, frame = cap.read() hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # define range of white color in HSV # change it according to your need ! sensitivity = 15 lower_white = np.array([0,0,255-sensitivity]) upper_white = np.array([255,sensitivity,255]) # Threshold the HSV image to get only white colors mask = cv2.inRange(hsv, lower_white, upper_white) # Bitwise-AND mask and original image res = cv2.bitwise_and(frame,frame, mask= mask) cv2.imshow('frame',frame) cv2.imshow('mask',mask) cv2.imshow('res',res) k = cv2.waitKey(5) & 0xFF if k == 27: break cv2.destroyAllWindows()
Well, first thing you should know what color space you are using. Just a small tutorial of color spaces in OpenCV for Mat
of type CV_8UC3
. (Images from Wikipedia)
HSV
In the HSV (Hue, Saturation, Value) color space, H gives the color dominant color, S the saturation of the color, V the lightness. In OpenCV, the ranges are different. S,V are in [0,255], while H is in [0, 180]. Typically H is in range [0,360] (the full circle), but to fit in a byte (256 different values) it's value is halved.
In HSV space is easier to separate a single color, since you can simply set the proper range for H, and just take care that S is not too small (it will be almost white), and V is not too small (it will be dark).
So for example, if you need almost blue colors, you need H to be around the value 120 (say in [110,130]), and S,V not too small (say in [100,255]).
White is not a hue (the rainbow doesn't have white color in it), but is a combination of color.
In HSV, you need to take all range of H (H in [0, 180]), very small S values (say S in [0, 25]), and very high V values (say V in [230, 255]). This basically corresponds to the upper part of the central axis of the cone.
So to make it track white objects in HSV space, you need:
lower_white = np.array([0, 0, 230]) upper_white = np.array([180, 25, 255])
Or, since you defined a sensitivity value, like:
sensitivity = 15 lower_white = np.array([0, 0, 255-sensitivity]) upper_white = np.array([180, sensitivity, 255])
For other colors:
green = 60; blue = 120; yellow = 30; ... sensitivity = 15 // Change color with your actual color lower_color = np.array([color - sensitivity, 100, 100]) upper_color = np.array([color + sensitivity, 255, 255])
Red H value is 0, so you need to take two ranges and "OR" them together:
sensitivity = 15 lower_red_0 = np.array([0, 100, 100]) upper_red_0 = np.array([sensitivity, 255, 255]) lower_red_1 = np.array([180 - sensitivity, 100, 100]) upper_red_1 = np.array([180, 255, 255]) mask_0 = cv2.inRange(hsv, lower_red_0 , upper_red_0); mask_1 = cv2.inRange(hsv, lower_red_1 , upper_red_1 ); mask = cv2.bitwise_or(mask1, mask2)
Now you should be able to track any color!