By the end of this post, you’ll have made a pretty basic HSV color trackbar/slider that filters out a range of colors, leaving you with the range of colors that you want to identify. HSV stands for ‘Hue, Saturation, Value’. It is composed of 3 separate values that determine the range of colors that you’d want to find.
If you just want the code, follow this link to my github
https://github.com/botforge/ColorTrackbar/blob/master/HSV%20Trackbar.py
Prerequisites
This tutorial assumes you have some degree of proficiency with Python and have dabbled around with OpenCV. If you haven’t touched OpenCV ever, this tutorial still has links to whatever you may need to know to complete writing this code.
1. Creating Trackbars
OpenCV has a pretty good tutorial on creating and reading multiple trackbars, but it digresses from the application we intend to use it for. Carefully reading the following section should suffice.
Don’t worry if you don’t get some of it, I’ll explain the important functions soon.
#import the necessary packages
import cv2
import numpy as np
#'optional' argument is required for trackbar creation parameters
def nothing:
pass
#Capture video from the stream
cap = cv2.VideoCapture(0)
cv2.namedWindow('Colorbars') //Create a window named 'Colorbars'
#assign strings for ease of coding
hh='Hue High'
hl='Hue Low'
sh='Saturation High'
sl='Saturation Low'
vh='Value High'
vl='Value Low'
wnd = 'Colorbars'
#Begin Creating trackbars for each
cv2.createTrackbar(hl, wnd,0,179,nothing)
cv2.createTrackbar(hh, wnd,0,179,nothing)
cv2.createTrackbar(sl, wnd',0,255,nothing)
cv2.createTrackbar(sh, wnd,0,255,nothing)
cv2.createTrackbar(vl, wnd,0,255,nothing)
cv2.createTrackbar(vh, wnd',0,255,nothing)
You may be wondering what the parameters of the cv2.createTrackbar() function are. The OpenCV documentation is the best place for a comprehensive explanation, but I’ll give you one more specific to the problem we’re solving.
So the parameters are as follows:
cv2.createTrackbar(trackbarname, windowname, minimum, maximum, argument)
We assigned our trackbar names in lines 13-18 and our window name in line 19. The minimum position of the trackbar for all instances is 0. In simpler terms, when you slide the slider, it won’t go below a value of 0 as no HSV values are negative. The maximum position varies. For the Hue values it goes from 0-180, and for Saturation and Val, it goes from 0-255.
There’s no need to concern yourself with why those numbers were chosen, but if your interested, there are a bunch of books by O’Reilly on safaribooksonline.com to learn about the mathematics behind computer vision.
2. Reading and processing Trackbars
Here’s where the real stuff comes in. As usual, don’t fret if you don’t get the code, but try reading and understanding as much as you can.
#begin our 'infinite' while loop
while(1):
#read the streamed frames (we previously named this cap)
_,frame=cap.read()
#it is common to apply a blur to the frame
frame=cv2.GaussianBlur(frame,(5,5),0)
#convert from a BGR stream to an HSV stream
hsv=cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
All we did here was read the stream we previously assigned as cap.
Reading the frame using the x.read() function returns a tuple. You can ignore the first value for now, and call the second value frame. This frame variable is actually an array of values. Each element of this array contains BGR (Blue, Green, Red) values. Concretely, each element is a pixel.
We also introduced a Gaussian Blur. This is commonly applied in order to reduce single pixel anomalies while searching the array. Read more about the Gaussian blur function here, but for the sake of simplicity, just remember that the first parameter is the array of pixels you receive from cap.read(), and the other numbers can generally remain untouched.
The conversion between BGR to HSV is analogous to the conversion between mp3 and wav for your music files. You’re essentially converting the data in the frame so it becomes readable in a different way. That’s what the cv2.cvtColor() function does. You then name your new array ‘hsv‘
#read trackbar positions for each trackbar
hul=cv2.getTrackbarPos(hl, wnd)
huh=cv2.getTrackbarPos(hh, wnd)
sal=cv2.getTrackbarPos(sl, wnd)
sah=cv2.getTrackbarPos(sh, wnd)
val=cv2.getTrackbarPos(vl, wnd)
vah=cv2.getTrackbarPos(vh, wnd)
#make array for final values
HSVLOW=np.array([hul,sal,val])
HSVHIGH=np.array([huh,sah,vah])
#create a mask for that range
mask = cv2.inRange(hsv,HSVLOW, HSVHIGH)
The stuff above is pretty self explanatory. You read the trackbars with cv2.getTrackbarPos() and assign them to variables (you can name them anything).
In lines 10-11, your final frame shouldn’t show the whole frame, it should only show the range specified by your trackbar. To do that, you have to make a numpy array with the lower HSV values, and one with your higher HSV values. You then have to create a mask to apply this range to the frame. That’s what cv2.inRange() does.
res = cv2.bitwise_and(frame,frame, mask =mask)
cv2.imshow(wnd, res)
k = cv2.waitKey(5) && 0xFF
if k == ord('q'):
break
cv2.destroyAllWindows()
The cv2.bitwise_and function allows you to display your mask (the HSV image with the filtered range) back onto your initial frame. cv2.imshow() takes 2 parameters, namely, window name and image array. We’ll keep our initial window name, and we’ll choose to display the res array, as that contains the filtered array displayed on the initial frame.
Lines 4-6 just allows you to quit the whole process by pressing ‘q’.
That’s about it. Now dabble around with the trackbars to find your desired color range. Next, Learn how to track a filtered object across the screen.