Skip to content

Commit 6df0a3d

Browse files
committed
updated counting code, removed usused imports
1 parent 88de483 commit 6df0a3d

4 files changed

+306
-252
lines changed

Diff for: centroidtracker.py

+158-157
Original file line numberDiff line numberDiff line change
@@ -3,161 +3,162 @@
33
from collections import OrderedDict
44
import numpy as np
55

6+
67
class CentroidTracker:
7-
def __init__(self, maxDisappeared=50, maxDistance=50):
8-
# initialize the next unique object ID along with two ordered
9-
# dictionaries used to keep track of mapping a given object
10-
# ID to its centroid and number of consecutive frames it has
11-
# been marked as "disappeared", respectively
12-
self.nextObjectID = 0
13-
self.objects = OrderedDict()
14-
self.disappeared = OrderedDict()
15-
16-
# store the number of maximum consecutive frames a given
17-
# object is allowed to be marked as "disappeared" until we
18-
# need to deregister the object from tracking
19-
self.maxDisappeared = maxDisappeared
20-
21-
# store the maximum distance between centroids to associate
22-
# an object -- if the distance is larger than this maximum
23-
# distance we'll start to mark the object as "disappeared"
24-
self.maxDistance = maxDistance
25-
26-
def register(self, centroid):
27-
# when registering an object we use the next available object
28-
# ID to store the centroid
29-
self.objects[self.nextObjectID] = centroid
30-
self.disappeared[self.nextObjectID] = 0
31-
self.nextObjectID += 1
32-
33-
def deregister(self, objectID):
34-
# to deregister an object ID we delete the object ID from
35-
# both of our respective dictionaries
36-
del self.objects[objectID]
37-
del self.disappeared[objectID]
38-
39-
def update(self, rects):
40-
# check to see if the list of input bounding box rectangles
41-
# is empty
42-
if len(rects) == 0:
43-
# loop over any existing tracked objects and mark them
44-
# as disappeared
45-
for objectID in list(self.disappeared.keys()):
46-
self.disappeared[objectID] += 1
47-
48-
# if we have reached a maximum number of consecutive
49-
# frames where a given object has been marked as
50-
# missing, deregister it
51-
if self.disappeared[objectID] > self.maxDisappeared:
52-
self.deregister(objectID)
53-
54-
# return early as there are no centroids or tracking info
55-
# to update
56-
return self.objects
57-
58-
# initialize an array of input centroids for the current frame
59-
inputCentroids = np.zeros((len(rects), 2), dtype="int")
60-
61-
# loop over the bounding box rectangles
62-
for (i, (startX, startY, endX, endY)) in enumerate(rects):
63-
# use the bounding box coordinates to derive the centroid
64-
cX = int((startX + endX) / 2.0)
65-
cY = int((startY + endY) / 2.0)
66-
inputCentroids[i] = (cX, cY)
67-
68-
# if we are currently not tracking any objects take the input
69-
# centroids and register each of them
70-
if len(self.objects) == 0:
71-
for i in range(0, len(inputCentroids)):
72-
self.register(inputCentroids[i])
73-
74-
# otherwise, are are currently tracking objects so we need to
75-
# try to match the input centroids to existing object
76-
# centroids
77-
else:
78-
# grab the set of object IDs and corresponding centroids
79-
objectIDs = list(self.objects.keys())
80-
objectCentroids = list(self.objects.values())
81-
82-
# compute the distance between each pair of object
83-
# centroids and input centroids, respectively -- our
84-
# goal will be to match an input centroid to an existing
85-
# object centroid
86-
D = dist.cdist(np.array(objectCentroids), inputCentroids)
87-
88-
# in order to perform this matching we must (1) find the
89-
# smallest value in each row and then (2) sort the row
90-
# indexes based on their minimum values so that the row
91-
# with the smallest value as at the *front* of the index
92-
# list
93-
rows = D.min(axis=1).argsort()
94-
95-
# next, we perform a similar process on the columns by
96-
# finding the smallest value in each column and then
97-
# sorting using the previously computed row index list
98-
cols = D.argmin(axis=1)[rows]
99-
100-
# in order to determine if we need to update, register,
101-
# or deregister an object we need to keep track of which
102-
# of the rows and column indexes we have already examined
103-
usedRows = set()
104-
usedCols = set()
105-
106-
# loop over the combination of the (row, column) index
107-
# tuples
108-
for (row, col) in zip(rows, cols):
109-
# if we have already examined either the row or
110-
# column value before, ignore it
111-
if row in usedRows or col in usedCols:
112-
continue
113-
114-
# if the distance between centroids is greater than
115-
# the maximum distance, do not associate the two
116-
# centroids to the same object
117-
if D[row, col] > self.maxDistance:
118-
continue
119-
120-
# otherwise, grab the object ID for the current row,
121-
# set its new centroid, and reset the disappeared
122-
# counter
123-
objectID = objectIDs[row]
124-
self.objects[objectID] = inputCentroids[col]
125-
self.disappeared[objectID] = 0
126-
127-
# indicate that we have examined each of the row and
128-
# column indexes, respectively
129-
usedRows.add(row)
130-
usedCols.add(col)
131-
132-
# compute both the row and column index we have NOT yet
133-
# examined
134-
unusedRows = set(range(0, D.shape[0])).difference(usedRows)
135-
unusedCols = set(range(0, D.shape[1])).difference(usedCols)
136-
137-
# in the event that the number of object centroids is
138-
# equal or greater than the number of input centroids
139-
# we need to check and see if some of these objects have
140-
# potentially disappeared
141-
if D.shape[0] >= D.shape[1]:
142-
# loop over the unused row indexes
143-
for row in unusedRows:
144-
# grab the object ID for the corresponding row
145-
# index and increment the disappeared counter
146-
objectID = objectIDs[row]
147-
self.disappeared[objectID] += 1
148-
149-
# check to see if the number of consecutive
150-
# frames the object has been marked "disappeared"
151-
# for warrants deregistering the object
152-
if self.disappeared[objectID] > self.maxDisappeared:
153-
self.deregister(objectID)
154-
155-
# otherwise, if the number of input centroids is greater
156-
# than the number of existing object centroids we need to
157-
# register each new input centroid as a trackable object
158-
else:
159-
for col in unusedCols:
160-
self.register(inputCentroids[col])
161-
162-
# return the set of trackable objects
163-
return self.objects
8+
def __init__(self, maxDisappeared=50, maxDistance=50):
9+
# initialize the next unique object ID along with two ordered
10+
# dictionaries used to keep track of mapping a given object
11+
# ID to its centroid and number of consecutive frames it has
12+
# been marked as "disappeared", respectively
13+
self.nextObjectID = 0
14+
self.objects = OrderedDict()
15+
self.disappeared = OrderedDict()
16+
17+
# store the number of maximum consecutive frames a given
18+
# object is allowed to be marked as "disappeared" until we
19+
# need to deregister the object from tracking
20+
self.maxDisappeared = maxDisappeared
21+
22+
# store the maximum distance between centroids to associate
23+
# an object -- if the distance is larger than this maximum
24+
# distance we'll start to mark the object as "disappeared"
25+
self.maxDistance = maxDistance
26+
27+
def register(self, centroid):
28+
# when registering an object we use the next available object
29+
# ID to store the centroid
30+
self.objects[self.nextObjectID] = centroid
31+
self.disappeared[self.nextObjectID] = 0
32+
self.nextObjectID += 1
33+
34+
def deregister(self, objectID):
35+
# to deregister an object ID we delete the object ID from
36+
# both of our respective dictionaries
37+
del self.objects[objectID]
38+
del self.disappeared[objectID]
39+
40+
def update(self, rects):
41+
# check to see if the list of input bounding box rectangles
42+
# is empty
43+
if len(rects) == 0:
44+
# loop over any existing tracked objects and mark them
45+
# as disappeared
46+
for objectID in list(self.disappeared.keys()):
47+
self.disappeared[objectID] += 1
48+
49+
# if we have reached a maximum number of consecutive
50+
# frames where a given object has been marked as
51+
# missing, deregister it
52+
if self.disappeared[objectID] > self.maxDisappeared:
53+
self.deregister(objectID)
54+
55+
# return early as there are no centroids or tracking info
56+
# to update
57+
return self.objects
58+
59+
# initialize an array of input centroids for the current frame
60+
inputCentroids = np.zeros((len(rects), 2), dtype="int")
61+
62+
# loop over the bounding box rectangles
63+
for (i, (startX, startY, endX, endY)) in enumerate(rects):
64+
# use the bounding box coordinates to derive the centroid
65+
cX = int((startX + endX) / 2.0)
66+
cY = int((startY + endY) / 2.0)
67+
inputCentroids[i] = (cX, cY)
68+
69+
# if we are currently not tracking any objects take the input
70+
# centroids and register each of them
71+
if len(self.objects) == 0:
72+
for i in range(0, len(inputCentroids)):
73+
self.register(inputCentroids[i])
74+
75+
# otherwise, are are currently tracking objects so we need to
76+
# try to match the input centroids to existing object
77+
# centroids
78+
else:
79+
# grab the set of object IDs and corresponding centroids
80+
objectIDs = list(self.objects.keys())
81+
objectCentroids = list(self.objects.values())
82+
83+
# compute the distance between each pair of object
84+
# centroids and input centroids, respectively -- our
85+
# goal will be to match an input centroid to an existing
86+
# object centroid
87+
D = dist.cdist(np.array(objectCentroids), inputCentroids)
88+
89+
# in order to perform this matching we must (1) find the
90+
# smallest value in each row and then (2) sort the row
91+
# indexes based on their minimum values so that the row
92+
# with the smallest value as at the *front* of the index
93+
# list
94+
rows = D.min(axis=1).argsort()
95+
96+
# next, we perform a similar process on the columns by
97+
# finding the smallest value in each column and then
98+
# sorting using the previously computed row index list
99+
cols = D.argmin(axis=1)[rows]
100+
101+
# in order to determine if we need to update, register,
102+
# or deregister an object we need to keep track of which
103+
# of the rows and column indexes we have already examined
104+
usedRows = set()
105+
usedCols = set()
106+
107+
# loop over the combination of the (row, column) index
108+
# tuples
109+
for (row, col) in zip(rows, cols):
110+
# if we have already examined either the row or
111+
# column value before, ignore it
112+
if row in usedRows or col in usedCols:
113+
continue
114+
115+
# if the distance between centroids is greater than
116+
# the maximum distance, do not associate the two
117+
# centroids to the same object
118+
if D[row, col] > self.maxDistance:
119+
continue
120+
121+
# otherwise, grab the object ID for the current row,
122+
# set its new centroid, and reset the disappeared
123+
# counter
124+
objectID = objectIDs[row]
125+
self.objects[objectID] = inputCentroids[col]
126+
self.disappeared[objectID] = 0
127+
128+
# indicate that we have examined each of the row and
129+
# column indexes, respectively
130+
usedRows.add(row)
131+
usedCols.add(col)
132+
133+
# compute both the row and column index we have NOT yet
134+
# examined
135+
unusedRows = set(range(0, D.shape[0])).difference(usedRows)
136+
unusedCols = set(range(0, D.shape[1])).difference(usedCols)
137+
138+
# in the event that the number of object centroids is
139+
# equal or greater than the number of input centroids
140+
# we need to check and see if some of these objects have
141+
# potentially disappeared
142+
if D.shape[0] >= D.shape[1]:
143+
# loop over the unused row indexes
144+
for row in unusedRows:
145+
# grab the object ID for the corresponding row
146+
# index and increment the disappeared counter
147+
objectID = objectIDs[row]
148+
self.disappeared[objectID] += 1
149+
150+
# check to see if the number of consecutive
151+
# frames the object has been marked "disappeared"
152+
# for warrants deregistering the object
153+
if self.disappeared[objectID] > self.maxDisappeared:
154+
self.deregister(objectID)
155+
156+
# otherwise, if the number of input centroids is greater
157+
# than the number of existing object centroids we need to
158+
# register each new input centroid as a trackable object
159+
else:
160+
for col in unusedCols:
161+
self.register(inputCentroids[col])
162+
163+
# return the set of trackable objects
164+
return self.objects

0 commit comments

Comments
 (0)