Defining the main class of the tracker

The constructor of the class is given as follows:

class Sort:
def __init__(self, max_age=2, min_hits=3):
self.max_age = max_age
self.min_hits = min_hits
self.trackers = []
self.count = 0

It stores two parameters:

  • The first parameter is max_age, which specifies how many consecutive times a tracker of a certain object can remain without an associated box before we consider the object to have gone from the scene and delete the tracker.
  • The second parameter is min_hits, which specifies how many consecutive times a tracker should be associated with a box so that we consider it to be a certain object. It also creates properties for storing the trackers and counting the total number of trackers during the instance lifetime.  

We also define a method for creating an ID of a tracker:

def next_id(self):
self.count += 1
return self.count

The method increments the count of the trackers by one and returns the number as the ID.

Now we are ready to define the update method, which will do the heavy lifting:

def update(self, dets):

The update method accepts detection boxes and covers the following steps:

  1. For all available trackers, it predicts their new locations and removes trackers with failed predictions right away: 
self.trackers = [
tracker for tracker in self.trackers if not np.any(
np.isnan(
tracker.predict()))]
  1.  We then get the predicted boxes of the trackers
trks = np.array([tracker.current_state for tracker in self.trackers])
  1. Then, we associate the boxes predicted by the trackers with the detection boxes: 
matched, unmatched_dets, unmatched_trks = associate_detections_to_trackers(
dets, trks)
  1. We then update the matched trackers with the associated detections: 
for detection_num, tracker_num in matched:
self.trackers[tracker_num].update(dets[detection_num])
  1. For all unmatched detections, we create new trackers that are initialized with the corresponding bounding box: 
for i in unmatched_dets:
self.trackers.append(KalmanBoxTracker(dets[i, :], self.next_id()))
  1. We then compose the return value as an array of the tracker box and tracker ID concatenations of the relevant trackers: 
ret = np.array([np.concatenate((trk.current_state, [trk.id + 1]))
for trk in self.trackers
if trk.time_since_update < 1 and trk.hit_streak >= self.min_hits])

In the previous codes snippet, we consider only those trackers that were updated with a detection box in the current frame and that have at least a hit_streak consecutive association with detection boxes. Depending on the particular application of the algorithm, you might want to change this behavior to make it a better fit for your needs.

  1. We then clean up the trackers by removing the ones that have not been updated with a new bounding box for a while: 
self.trackers = [
tracker for tracker in self.trackers if tracker.time_since_update <= self.max_age]
  1.  At last, we return the results: 
return ret

So, now that we have completed the implementation of the algorithm, we have everything ready to run the app and see it in action. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.29.48