@@ -79,8 +79,8 @@ def update(self, states):
7979 number_of_states = states .shape [0 ]
8080
8181 number_of_tracked_objects = len (self .__tracked_objects )
82- objects_to_match = [i for i in range (0 , number_of_tracked_objects )]
83- states_to_match = [i for i in range (0 , number_of_states )]
82+ objects_to_match = list ( [i for i in range (0 , number_of_tracked_objects )])
83+ states_to_match = list ( [i for i in range (0 , number_of_states )])
8484
8585 ## Build the distance matrix and match objects
8686 # We build a matrix that contains the distances of the tracked objects
@@ -101,40 +101,47 @@ def update(self, states):
101101 # Clearly, this is not the optimal solution (but fast), since it doesn't
102102 # optimize for the cumulative distance of pairs
103103 # Whenever a minimum was found, we invalidate this part in the distance matrix
104- min_distances = np . min ( distance_matrix , axis = 1 )
105- min_distances = np .sort ( min_distances )
106-
107- for d in min_distances :
104+ while True :
105+ min_distance = np .min ( distance_matrix )
106+ index = np . argwhere ( distance_matrix == min_distance )[ 0 ]
107+
108108 # when the distance threshold is exceeded, it means we are seeing new objects,
109109 # or existing ones shall be removed
110- if d > self .distance_threshold :
110+ if min_distance > self .distance_threshold :
111111 break
112112
113- index = np .argwhere (distance_matrix == d )[0 ]
114113 t = index [0 ] # just to avoid confusion, this is the object
115114 s = index [1 ] # and this the state
116- distance_matrix [t , :] = np .inf # invalidate this part of the distance matrix
117-
118- objects_to_match .remove (t )
119- states_to_match .remove (s )
120- self .__tracked_objects [t ].update (states [s ])
121-
122- ## Add objects
123- # now go through all unmatched objects and create new objects
124- for i in states_to_match :
125- self .object_counter += 1
126- added_object = TrackedObject (self .object_counter , deepcopy (self .__filter_prototype ))
127- added_object .update (states [i ])
128- self .__tracked_objects .append (added_object )
115+ distance_matrix [t , s ] = np .inf # invalidate this part of the distance matrix
116+
117+ # if the state has not previously been associated to a tracked object
118+ if t in objects_to_match and s in states_to_match :
119+ objects_to_match .remove (t )
120+ states_to_match .remove (s )
121+ self .__tracked_objects [t ].update (states [s ])
129122
130123 ## Delete objects
131124 # Remove an object that has not been seen when its time-to-live is exceeded
125+ # We are using two steps for deletion, because in the first step we are addressing by index and we
126+ # don't want to mess up the list indexing
127+ removals = []
132128 for i in objects_to_match :
133129 tracked_object = self .__tracked_objects [i ]
134130 tracked_object .time_to_live += 1
135131
136132 if tracked_object .time_to_live > self .time_to_live :
137- self . __tracked_objects . remove (tracked_object )
133+ removals . append (tracked_object )
138134 else :
139135 # update the object with the next predicted state
140136 tracked_object .update (tracked_object .eval (time = 1 ))
137+
138+ for tracked_object in removals :
139+ self .__tracked_objects .remove (tracked_object )
140+
141+ ## Add objects
142+ # now go through all unmatched objects and create new objects
143+ for i in states_to_match :
144+ self .object_counter += 1
145+ added_object = TrackedObject (self .object_counter , deepcopy (self .__filter_prototype ))
146+ added_object .update (states [i ])
147+ self .__tracked_objects .append (added_object )
0 commit comments