Params: dets - a numpy array of detections in the format [[x1,y1,x2,y2,score],[x1,y1,x2,y2,score],...] Requires: this method must be called once for each frame even with empty detections. Returns the a similar array, where the last column is the object ID.
(self, dets)
| 175 | self.frame_count = 0 |
| 176 | |
| 177 | def update(self, dets): |
| 178 | """ |
| 179 | Params: |
| 180 | dets - a numpy array of detections in the format [[x1,y1,x2,y2,score],[x1,y1,x2,y2,score],...] |
| 181 | Requires: this method must be called once for each frame even with empty detections. |
| 182 | Returns the a similar array, where the last column is the object ID. |
| 183 | |
| 184 | NOTE: The number of objects returned may differ from the number of detections provided. |
| 185 | """ |
| 186 | self.frame_count += 1 |
| 187 | # get predicted locations from existing trackers. |
| 188 | trks = np.zeros((len(self.trackers), 5)) |
| 189 | to_del = [] |
| 190 | ret = [] |
| 191 | for t, trk in enumerate(trks): |
| 192 | pos = self.trackers[t].predict()[0] |
| 193 | trk[:] = [pos[0], pos[1], pos[2], pos[3], 0] |
| 194 | if np.any(np.isnan(pos)): |
| 195 | to_del.append(t) |
| 196 | trks = np.ma.compress_rows(np.ma.masked_invalid(trks)) |
| 197 | for t in reversed(to_del): |
| 198 | self.trackers.pop(t) |
| 199 | matched, unmatched_dets, unmatched_trks = associate_detections_to_trackers(dets, trks) |
| 200 | |
| 201 | # update matched trackers with assigned detections |
| 202 | for t, trk in enumerate(self.trackers): |
| 203 | if t not in unmatched_trks: |
| 204 | d = matched[np.where(matched[:, 1] == t)[0], 0] # d: [n] |
| 205 | trk.update(dets[d, :][0]) |
| 206 | |
| 207 | # create and initialise new trackers for unmatched detections |
| 208 | for i in unmatched_dets: |
| 209 | trk = KalmanBoxTracker(dets[i, :]) |
| 210 | self.trackers.append(trk) |
| 211 | i = len(self.trackers) |
| 212 | for trk in reversed(self.trackers): |
| 213 | d = trk.get_state()[0] |
| 214 | if ((trk.time_since_update < 1) and (trk.hit_streak >= self.min_hits or self.frame_count <= self.min_hits)): |
| 215 | ret.append(np.concatenate((d, [trk.id + 1])).reshape(1, -1)) # +1 as MOT benchmark requires positive |
| 216 | i -= 1 |
| 217 | # remove dead tracklet |
| 218 | if (trk.time_since_update > self.max_age): |
| 219 | self.trackers.pop(i) |
| 220 | if (len(ret) > 0): |
| 221 | return np.concatenate(ret) |
| 222 | return np.empty((0, 5)) |
| 223 | |
| 224 | |
| 225 | def parse_args(): |
no test coverage detected