Python OpenCV Color Tracking

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

enter image description here

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!

Leave a Comment