Color Tracking opencv-python and my first post!

This is my first post and I decided to post about my recent obsession towards Computer Vision. I am still a noob working my way out. Most of the time I take my vision for granted, it amazes me how one needs to understand mathematical concepts to work with computer vision which is not as intuitive as that of my vision.

I have always skipped learning python and am not a great fan of script style programming languages. I worked with opencv (c++) and I found that I need to type in huge number of lines and I needed manage memory. The fact that computer vision is mind bending and writing housekeeping codes in c++ is like adding salt to the wound.

OpenCV comes with python interface(duh!). I gave python a try. I was cursing myself for not having learnt it. No need of memory management, no need of typecasting variables *bliss*.

I would recommend you to learn python from this book from Swaroop. It is neat and simple.

Now coming back to business, I have included the program for tracking a blue coloured object below. The program follows these steps for tracking the blue coloured object

  • Find the approximate HSV colour range of the object of interest using gimp or ms paint.
  • Block the pixels which are not falling in the range and shoot up the pixel values to 255 which are in the range, so that we get a binary image.
  • Calculate the centroid of the blob formed in the binary image using image moments.
  • Track the motion of the centroid and draw a line trailing its path.

I have used the logic from Aishack and there is detailed explanation there.

(Please make sure that the indentation is correct, in case you copy the program, gist is sometimes buggy :( )

[gist id="4379792" file="colortrack.py"]

<pre>from cv import *  #bad practice, its just that am bit lazy

def GetThresholdedImage(img):
#returns thresholded image of the blue bottle
	imgHSV = CreateImage(GetSize(img), 8, 3)
#converts a BGR image to HSV
	CvtColor(img, imgHSV, CV_BGR2HSV)
	imgThreshed = CreateImage(GetSize(img), 8, 1)
#InRangeS takes source, lowerbound color, upperbound color and destination
#It converts the pixel values lying within the range to 255 and stores it in
#the destination
    InRangeS(imgHSV, (100, 94, 84), (109, 171, 143), imgThreshed)
	return imgThreshed

def main():
	color_tracker_window = "output"
	thresh_window = "thresh"
	capture = CaptureFromCAM(-1)
	NamedWindow( color_tracker_window, 1 ) 
	NamedWindow( thresh_window, 1 ) 
	imgScrible = None
	posX = 0
	posY = 0
	while True:

		frame = QueryFrame(capture)
		Smooth(frame, frame, CV_BLUR, 3)

		if(imgScrible is None):
			imgScrible = CreateImage(GetSize(frame), 8, 3)

		imgBlueThresh = GetThresholdedImage(frame)

		mat = GetMat(imgBlueThresh)
#Calculating the moments
        moments = Moments(mat, 0) 
      	area = GetCentralMoment(moments, 0, 0)
		moment10 = GetSpatialMoment(moments, 1, 0)
		moment01 = GetSpatialMoment(moments, 0,1)

#lastX and lastY stores the previous positions
		lastX = posX
		lastY = posY
#Finding a big enough blob
		if(area > 100000): 
			global posX
			global posY
#Calculating the coordinate postition of the centroid
			posX = int(moment10 / area)
			posY = int(moment01 / area)

			print 'x: ' + str(posX) + ' y: ' + str(posY) + ' area: ' + str(area)
#drawing lines to track the movement of the blob
			if(lastX > 0 and lastY > 0 and posX > 0 and posY > 0):
				Line(imgScrible, (posX, posY), (lastX, lastY), Scalar(0, 255, 255), 5)
#Adds the three layers and stores it in the frame
#frame -> it has the camera stream
#imgScrible -> it has the line tracking the movement of the blob
			Add(frame, imgScrible, frame)

            ShowImage(thresh_window, imgBlueThresh)
			ShowImage(color_tracker_window, frame)
			c = WaitKey(10)
			if(c!=-1):
				break

	return;
if __name__ == "__main__":
	main()

There are a few bugs in the program, the execution freezes once the object of interest is out of the frame and  some warnings due to sloppy handling of global variables. ( Need to get my python right, learning! The problem is that there is no static variables in python, need to find a workaround)

Note that softwares like Gimp and MS paint uses Hue(H) value ranging from 0-360 degrees and 0-100% for Saturation(S) and Value(V). But OpenCV uses 0-180 degs for Hue and 0-255 for Saturation and Value. So you need convert to OpenCV’s HSV convention.

ocvH = (H/360)*180
ocvS = (S/100)*255
ocvV = (V/100)*255
Next post I will correct those bugs!
UPDATE: Corrected those bugs.

4 thoughts on “Color Tracking opencv-python and my first post!