Skip to content

Object tracking with OpenCV

In this tutorial we will look at how to perform object tracking with OpenCV and different tracking algorithms available.


Pre Requisite

Make sure you have the OpenCV version 3.4+ for the code to work properly.


Import packages

Import the cv2 package. Some of the old trackers have been moved to legacy package so we need to import cv2.legacy as well.

1
2
3
import cv2 as cv
import cv2.legacy as cvl
import time as t

Tracker Menu

We first create a tracker menu to choose from when we run the program. In this tutorial we will be looking at 7 trackers.

1
2
3
4
5
6
7
8
9
print("--------- Select Tracker Types ---------")
print("1. Boosting")
print("2. MIL")
print("3. KCF")
print("4. TLD")
print("5. MedianFlow")
print("6. CSRT")
print("7. MOSSE")
type = int(input("Tracker no: "))

Note

For detailed explaination on how the algorithms work please check out this article.


Create Tracker Object

Next, we initialise the appropriate tracker based on the option chosen at the start.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
tracker_types = ['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW', 'CSRT', 'MOSSE']
tracker_type = tracker_types[type-1]

print("Tracker Initialised: ",tracker_type)
if tracker_type == 'BOOSTING':
    tracker = cvl.TrackerBoosting_create()
if tracker_type == 'MIL':
    tracker = cv.TrackerMIL_create()
if tracker_type == 'KCF':
    tracker = cv.TrackerKCF_create()
if tracker_type == 'TLD':
    tracker = cvl.TrackerTLD_create()
if tracker_type == 'MEDIANFLOW':
    tracker = cvl.TrackerMedianFlow_create()
if tracker_type == 'CSRT':
    tracker = cv.TrackerCSRT_create()
if tracker_type == 'MOSSE':
    tracker = cvl.TrackerMOSSE_create()

Initialise the Tracker

In this step we first start the video capture through webcam device connected to the machine. Then we read the first frame that we received from the camera and set the bounding box/region of interest on the frame around the object we want to tracker.

To draw the box just left click and drag the mouse over the object. Once select release the mouse and click enter.

1
2
3
4
5
cap = cv.VideoCapture(0)
t.sleep(2)
success, frame = cap.read()
roi = cv.selectROI("Track",frame, False)
tracker.init(frame, roi)

Note

We have added a small sleep time before reading the first frame because it take so time for OpenCV to completely initialise the VideoCapture and read frame. So the sleep time provides time for OpenCV to warmup else if we start reading too soon we may receive a black frame as output.


Tracking the object.

Next we read the frames coming from webcam and keep updating tracker. On updating the tracker we get the bounding box with co-ordinates for the new position of the object being tracking.

1
2
3
4
while True:
    timer = cv.getTickCount()
    success, img = cap.read()
    success, roi = tracker.update(img)

Updating ROI

Once we have the new co-ordinates for the bounding box we update the rectangle position and display the output. This continues till the frames are coming.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
while True:
    timer = cv.getTickCount()
    success, img = cap.read()
    success, roi = tracker.update(img)

    if success:
        x, y, w, h = int(roi[0]), int(roi[1]), int(roi[2]), int(roi[3])
        cv.rectangle(img, (x, y), ((x + w), (y + h)), (255, 0, 255), 3, 3 )

        cv.imshow("Tracking", img)

Stop the application

Finally, to stop reading the video frames and end the tracking click the key 'q' on the keyboard.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
while True:
    timer = cv.getTickCount()
    success, img = cap.read()
    success, roi = tracker.update(img)

    if success:
        x, y, w, h = int(roi[0]), int(roi[1]), int(roi[2]), int(roi[3])
        cv.rectangle(img, (x, y), ((x + w), (y + h)), (255, 0, 255), 3, 3 )

        cv.imshow("Tracking", img)
        if cv.waitKey(1) & 0xff == ord('q'):
            break

Complete Code

Once you run the application pass the tracker algorithm you want to use and press enter, then select the bounding box and press enter to start tracking. When you want to quit simply press key 'q'. Try to run the program with different tracker see which performs best.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import cv2 as cv
import cv2.legacy as cvl
import time as t

print("--------- Select Tracker Types ---------")
print("1. Boosting")
print("2. MIL")
print("3. KCF")
print("4. TLD")
print("5. MedianFlow")
print("6. CSRT")
print("7. MOSSE")
type = int(input("Tracker no: "))

tracker_types = ['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW', 'CSRT', 'MOSSE']
tracker_type = tracker_types[type-1]

print("Tracker Initialised: ",tracker_type)
if tracker_type == 'BOOSTING':
    tracker = cvl.TrackerBoosting_create()
if tracker_type == 'MIL':
    tracker = cv.TrackerMIL_create()
if tracker_type == 'KCF':
    tracker = cv.TrackerKCF_create()
if tracker_type == 'TLD':
    tracker = cvl.TrackerTLD_create()
if tracker_type == 'MEDIANFLOW':
    tracker = cvl.TrackerMedianFlow_create()
if tracker_type == 'CSRT':
    tracker = cv.TrackerCSRT_create()
if tracker_type == 'MOSSE':
    tracker = cvl.TrackerMOSSE_create()



cap = cv.VideoCapture(0)
t.sleep(2)
success, frame = cap.read()
roi = cv.selectROI("Track",frame, False)
tracker.init(frame, roi)


while True:

    timer = cv.getTickCount()
    success, img = cap.read()
    success, roi = tracker.update(img)

    if success:
        x, y, w, h = int(roi[0]), int(roi[1]), int(roi[2]), int(roi[3])
        cv.rectangle(img, (x, y), ((x + w), (y + h)), (255, 0, 255), 3, 3 )
        cv.putText(img, "Tracker Activated", (100, 75), cv.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
    else:
        cv.putText(img, "Tracker Lost", (100, 75), cv.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)

    cv.putText(img, "Fps:", (20, 40), cv.FONT_HERSHEY_SIMPLEX, 0.7, (255,0,255), 2);
    cv.putText(img, "Status:", (20, 75), cv.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 255), 2);

    fps = cv.getTickFrequency() / (cv.getTickCount() - timer);
    cv.putText(img,str(int(fps)), (75, 40), cv.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2);

    cv.imshow("Tracking", img)
    if cv.waitKey(1) & 0xff == ord('q'):
       break

cap.release()
cv.destroyAllWindows()