Tracking Example

This example shows how a single object that is already detected can be tracked. The tracking can be done using OpenCV tracking implementations.

First of all, all the required liberaries should be imported.

[1]:
from offlinemot.utils_ import resize
from offlinemot.fix_view import FixView
from offlinemot.background_subtraction import BG_subtractor
from offlinemot.objects_classes import TrafficObj
from offlinemot.config import configs
[2]:
import numpy as np
import cv2
import os

Now the sample video should be read with a video reader object from Opencv library

[3]:
cfg = configs()
cap = cv2.VideoCapture(os.path.join(cfg.cwd,'model','sample.mp4'))
ret, bg = cap.read() # read the first frame

We can start the tracking from the first frame, or from another later frame by writing:

[4]:
frame_id = 10 # the frame that should we start from
cap.set(1, frame_id-1)
[4]:
True

Then the first reference frame is read as follows

[5]:
ret,bg_rgb = cap.read()

We initialize the fix view and background subtractor objects. Theses objects are needed only for detecting on the first time, then the tracking object is started

[6]:
Fix_obj = FixView(bg_rgb,config=cfg)
BG_s = BG_subtractor(bg,config=cfg)
ret, frame = cap.read()

To start fixing each frame at the start we need the forground mask. For that we can run the background subtarction one time before the main loop

[7]:
fg_img= BG_s.bg_substract(frame)

Creating the tracker objects

Now to get the boxes that we want to start with we can run the following which will get the objects from the forground

[8]:
I_com, fg_objs = BG_s.get_big_objects(fg_img,frame)

From fg_objs we create the traffic objects. Note that we can set another type of trackers than TrackerKCF_create to TrackerMIL_create or TrackerMedianFlow_create. But the first (the default one) has the feature of getting the failing states as well.

At the end what we will have is a list of objects ready to be tarcked in the video

[9]:
output = []
for obj_item in fg_objs:
    box = [obj_item.bbox[1],obj_item.bbox[0],obj_item.bbox[3]-obj_item.bbox[1],obj_item.bbox[2]-obj_item.bbox[0]]

    if all(box) and (obj_item.area > 1000):
        # to avoid objects at edge
        new_obj = TrafficObj(frame,frame_id,box,-1,config=cfg,class_id=-1,detection_way=3,tracker=cv2.TrackerKCF_create)
        output.append(new_obj)

to see how much objects we have we can type

[10]:
print(len(output))
3

Main loop

Now it is time to start the fixing and background substarction loop. The result will be shown in a new window

The video will keep running until you hit ESC or the video end

[11]:
while ret:
    frame_id += 1

    frame = Fix_obj.fix_view(frame,fg_img)
    I_com = BG_s.bg_substract(frame)

    #print(frame_id)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
    ret, frame = cap.read()
    new_frame = frame.copy()
    for obj in output:
        obj.track(frame,frame_id)
        new_frame = obj.draw(new_frame)

    cv2.imshow('fgmask', resize(new_frame,0.2))

cap.release()
cv2.destroyAllWindows()

The result shows the initial objects tracked, but not any new ones. This is because a repeated detection step is needed to detect and track any new object (not just tracking).