From 2a2245552db524d3d93174ac830aa2d0e39b2e97 Mon Sep 17 00:00:00 2001 From: adam-dziedzic Date: Wed, 20 Feb 2019 21:19:41 -0600 Subject: [PATCH 1/2] add lables to detections --- demo.py | 7 ++++--- iou_tracker.py | 24 ++++++++++++++++-------- mot16.py | 21 +++++++++++++-------- mot17.py | 26 +++++++++++++++++--------- seqmaps/mot16-dpm-all.txt | 15 +++++++++++++++ seqmaps/mot16-dpm-test.txt | 8 ++++++++ seqmaps/mot16-dpm-train.txt | 8 ++++++++ util.py | 21 +++++++++++++-------- 8 files changed, 94 insertions(+), 36 deletions(-) create mode 100644 seqmaps/mot16-dpm-all.txt create mode 100644 seqmaps/mot16-dpm-test.txt create mode 100644 seqmaps/mot16-dpm-train.txt diff --git a/demo.py b/demo.py index 21dde6b..9ef45f2 100755 --- a/demo.py +++ b/demo.py @@ -18,7 +18,8 @@ def main(args): detections = load_mot(args.detection_path) start = time() - tracks = track_iou(detections, args.sigma_l, args.sigma_h, args.sigma_iou, args.t_min) + tracks = track_iou(detections, args.sigma_l, args.sigma_h, args.sigma_iou, + args.t_min) end = time() num_frames = len(detections) @@ -28,12 +29,12 @@ def main(args): if __name__ == '__main__': - parser = argparse.ArgumentParser(description="IOU Tracker demo script") parser.add_argument('-d', '--detection_path', type=str, required=True, help="full path to CSV file containing the detections") parser.add_argument('-o', '--output_path', type=str, required=True, - help="output path to store the tracking results (MOT challenge devkit compatible format)") + help="output path to store the tracking results " + "(MOT challenge devkit compatible format)") parser.add_argument('-sl', '--sigma_l', type=float, default=0, help="low detection threshold") parser.add_argument('-sh', '--sigma_h', type=float, default=0.5, diff --git a/iou_tracker.py b/iou_tracker.py index 12cd6bb..799d1c5 100644 --- a/iou_tracker.py +++ b/iou_tracker.py @@ -13,11 +13,13 @@ def track_iou(detections, sigma_l, sigma_h, sigma_iou, t_min): """ Simple IOU based tracker. - See "High-Speed Tracking-by-Detection Without Using Image Information by E. Bochinski, V. Eiselein, T. Sikora" for + See "High-Speed Tracking-by-Detection Without Using Image Information + by E. Bochinski, V. Eiselein, T. Sikora" for more information. Args: - detections (list): list of detections per frame, usually generated by util.load_mot + detections (list): list of detections per frame, usually generated by + util.load_mot sigma_l (float): low detection threshold. sigma_h (float): high detection threshold. sigma_iou (float): IOU threshold. @@ -38,10 +40,12 @@ def track_iou(detections, sigma_l, sigma_h, sigma_iou, t_min): for track in tracks_active: if len(dets) > 0: # get det with highest iou - best_match = max(dets, key=lambda x: iou(track['bboxes'][-1], x['bbox'])) + best_match = max(dets, key=lambda x: iou(track['bboxes'][-1], + x['bbox'])) if iou(track['bboxes'][-1], best_match['bbox']) >= sigma_iou: track['bboxes'].append(best_match['bbox']) - track['max_score'] = max(track['max_score'], best_match['score']) + track['max_score'] = max(track['max_score'], + best_match['score']) updated_tracks.append(track) @@ -51,16 +55,19 @@ def track_iou(detections, sigma_l, sigma_h, sigma_iou, t_min): # if track was not updated if len(updated_tracks) == 0 or track is not updated_tracks[-1]: # finish track when the conditions are met - if track['max_score'] >= sigma_h and len(track['bboxes']) >= t_min: + if track['max_score'] >= sigma_h and len( + track['bboxes']) >= t_min: tracks_finished.append(track) # create new tracks - new_tracks = [{'bboxes': [det['bbox']], 'max_score': det['score'], 'start_frame': frame_num} for det in dets] + new_tracks = [{'bboxes': [det['bbox']], 'max_score': det['score'], + 'start_frame': frame_num} for det in dets] tracks_active = updated_tracks + new_tracks # finish all remaining active tracks tracks_finished += [track for track in tracks_active - if track['max_score'] >= sigma_h and len(track['bboxes']) >= t_min] + if track['max_score'] >= sigma_h and len( + track['bboxes']) >= t_min] return tracks_finished @@ -91,7 +98,8 @@ def track_iou_matlab_wrapper(detections, sigma_l, sigma_h, sigma_iou, t_min): out = [] for track in tracks: for i, bbox in enumerate(track['bboxes']): - out += [float(bbox[0]), float(bbox[1]), float(bbox[2] - bbox[0]), float(bbox[3] - bbox[1]), + out += [float(bbox[0]), float(bbox[1]), float(bbox[2] - bbox[0]), + float(bbox[3] - bbox[1]), float(track['start_frame'] + i), float(id_)] id_ += 1 diff --git a/mot16.py b/mot16.py index de8f42a..f2a83f5 100755 --- a/mot16.py +++ b/mot16.py @@ -28,24 +28,29 @@ def main(args): detections = load_mot(det_path) start = time() - tracks = track_iou(detections, args.sigma_l, args.sigma_h, args.sigma_iou, args.t_min) + tracks = track_iou(detections, args.sigma_l, args.sigma_h, + args.sigma_iou, args.t_min) end = time() num_frames = len(detections) - print("finished " + seq + " at " + str(int(num_frames / (end - start))) + " fps!") + print("finished " + seq + " at " + str( + int(num_frames / (end - start))) + " fps!") save_to_csv(out_path, tracks) if __name__ == '__main__': - - parser = argparse.ArgumentParser(description="IOU Tracker MOT demo script. Default parameters are set to reproduce " - "the results using the SDP detections.") - parser.add_argument('-m', '--seqmap', type=str, required=True, + parser = argparse.ArgumentParser( + description="IOU Tracker MOT demo script. Default parameters are set to " + "reproduce the results using the SDP detections.") + parser.add_argument('-m', '--seqmap', type=str, + default="../motchallenge/seqmaps/c5-train.txt", help="full path to the seqmap file to evaluate") - parser.add_argument('-o', '--res_dir', type=str, required=True, + parser.add_argument('-o', '--res_dir', type=str, + default="../motchallenge/res/MOT16/iou-tracker", help="path to the results directory") - parser.add_argument('-b', '--benchmark_dir', type=str, required=True, + parser.add_argument('-b', '--benchmark_dir', type=str, + default="../motchallenge/MOT16/train", help="path to the sequence directory") parser.add_argument('-sl', '--sigma_l', type=float, default=0.3, help="low detection threshold") diff --git a/mot17.py b/mot17.py index be179f0..6ba32a6 100755 --- a/mot17.py +++ b/mot17.py @@ -38,10 +38,13 @@ def main(args): sigma_iou = 0.2 t_min = 2 else: - print("No detector name found, this could happen with the wrong seqmap seqmap file. " - "Please use c10-train.txt, c10-test.txt or c10-all.txt") + print( + "No detector name found, this could happen with the " + "wrong seqmap seqmap file. " + "Please use c10-train.txt, c10-test.txt or c10-all.txt") exit() + # Take the pre-computed detections. det_path = args.benchmark_dir + "/" + seq + "/det/det.txt" out_path = args.res_dir + "/" + seq + ".txt" @@ -52,19 +55,24 @@ def main(args): end = time() num_frames = len(detections) - print("finished " + seq + " at " + str(int(num_frames / (end - start))) + " fps!") + print("finished " + seq + " at " + str( + int(num_frames / (end - start))) + " fps!") save_to_csv(out_path, tracks) -if __name__ == '__main__': - parser = argparse.ArgumentParser(description="IOU Tracker MOT17 demo script. The best parameters for each detector " - "are hardcoded.") - parser.add_argument('-m', '--seqmap', type=str, required=True, +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="IOU Tracker MOT17 demo script. The best parameters for " + "each detector are hardcoded.") + parser.add_argument('-m', '--seqmap', type=str, + default="../motchallenge/seqmaps/c10-train-sample.txt", help="full path to the seqmap file to evaluate") - parser.add_argument('-o', '--res_dir', type=str, required=True, + parser.add_argument('-o', '--res_dir', type=str, + default="../motchallenge/res/MOT17/iou-tracker", help="path to the results directory") - parser.add_argument('-b', '--benchmark_dir', type=str, required=True, + parser.add_argument('-b', '--benchmark_dir', type=str, + default="../motchallenge/", help="path to the sequence directory") args = parser.parse_args() diff --git a/seqmaps/mot16-dpm-all.txt b/seqmaps/mot16-dpm-all.txt new file mode 100644 index 0000000..3589dc7 --- /dev/null +++ b/seqmaps/mot16-dpm-all.txt @@ -0,0 +1,15 @@ +name +MOT16-01 +MOT16-02 +MOT16-03 +MOT16-04 +MOT16-05 +MOT16-06 +MOT16-07 +MOT16-08 +MOT16-09 +MOT16-10 +MOT16-11 +MOT16-12 +MOT16-13 +MOT16-14 diff --git a/seqmaps/mot16-dpm-test.txt b/seqmaps/mot16-dpm-test.txt new file mode 100644 index 0000000..b54430a --- /dev/null +++ b/seqmaps/mot16-dpm-test.txt @@ -0,0 +1,8 @@ +name +MOT16-01 +MOT16-03 +MOT16-06 +MOT16-07 +MOT16-08 +MOT16-12 +MOT16-14 diff --git a/seqmaps/mot16-dpm-train.txt b/seqmaps/mot16-dpm-train.txt new file mode 100644 index 0000000..1bbb0bd --- /dev/null +++ b/seqmaps/mot16-dpm-train.txt @@ -0,0 +1,8 @@ +name +MOT16-02 +MOT16-04 +MOT16-05 +MOT16-09 +MOT16-10 +MOT16-11 +MOT16-13 diff --git a/util.py b/util.py index f7d5cd0..706fcb5 100644 --- a/util.py +++ b/util.py @@ -11,8 +11,9 @@ def load_mot(detections): """ - Loads detections stored in a mot-challenge like formatted CSV or numpy array (fieldNames = ['frame', 'id', 'x', 'y', - 'w', 'h', 'score']). + Loads detections stored in a mot-challenge like formatted CSV or numpy array + (fieldNames = ['frame', 'id', 'x', 'y', 'w', 'h', 'score', 'class', + 'visibility_ratio']). Args: detections @@ -26,18 +27,21 @@ def load_mot(detections): raw = np.genfromtxt(detections, delimiter=',', dtype=np.float32) else: # assume it is an array - assert isinstance(detections, np.ndarray), "only numpy arrays or *.csv paths are supported as detections." + assert isinstance(detections, + np.ndarray), "only numpy arrays or *.csv paths are supported as detections." raw = detections.astype(np.float32) end_frame = int(np.max(raw[:, 0])) - for i in range(1, end_frame+1): + for i in range(1, end_frame + 1): idx = raw[:, 0] == i bbox = raw[idx, 2:6] bbox[:, 2:4] += bbox[:, 0:2] # x1, y1, w, h -> x1, y1, x2, y2 scores = raw[idx, 6] + labels = raw[idx, 7] # extract column 7 for the indexes (idx) from raw dets = [] - for bb, s in zip(bbox, scores): - dets.append({'bbox': (bb[0], bb[1], bb[2], bb[3]), 'score': s}) + for bb, s, label in zip(bbox, scores, labels): + dets.append({'bbox': (bb[0], bb[1], bb[2], bb[3]), 'score': s, + 'label': label}) data.append(dets) return data @@ -52,8 +56,9 @@ def save_to_csv(out_path, tracks): tracks (list): list of tracks to store. """ - with open(out_path, "w") as ofile: - field_names = ['frame', 'id', 'x', 'y', 'w', 'h', 'score', 'wx', 'wy', 'wz'] + with open(out_path, "w", newline="") as ofile: + field_names = ['frame', 'id', 'x', 'y', 'w', 'h', 'score', 'wx', 'wy', + 'wz'] odict = csv.DictWriter(ofile, field_names) id_ = 1 From 1d13ea8d1cf82818055e0d8cf891558f0af76246 Mon Sep 17 00:00:00 2001 From: adam-dziedzic Date: Wed, 27 Feb 2019 11:00:34 -0600 Subject: [PATCH 2/2] iou tracker takes detections from yolo/ssd --- iou_tracker.py | 1 + mot16.py | 7 +++++-- util.py | 11 ++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/iou_tracker.py b/iou_tracker.py index 799d1c5..0717a0b 100644 --- a/iou_tracker.py +++ b/iou_tracker.py @@ -46,6 +46,7 @@ def track_iou(detections, sigma_l, sigma_h, sigma_iou, t_min): track['bboxes'].append(best_match['bbox']) track['max_score'] = max(track['max_score'], best_match['score']) + track['label'] = best_match['label'] updated_tracks.append(track) diff --git a/mot16.py b/mot16.py index f2a83f5..e8f5a5c 100755 --- a/mot16.py +++ b/mot16.py @@ -13,6 +13,9 @@ from iou_tracker import track_iou from util import load_mot, save_to_csv +# version = "" +version = "_yolo" + def main(args): with open(args.seqmap) as fd: @@ -22,8 +25,8 @@ def main(args): if seq == "name" or seq == "": continue else: - det_path = args.benchmark_dir + "/" + seq + "/det/det.txt" - out_path = args.res_dir + "/" + seq + ".txt" + det_path = args.benchmark_dir + "/" + seq + "/det" + version + "/det.txt" + out_path = args.res_dir + "/" + seq + version + ".txt" detections = load_mot(det_path) diff --git a/util.py b/util.py index 706fcb5..c8cc4ad 100644 --- a/util.py +++ b/util.py @@ -40,8 +40,9 @@ def load_mot(detections): labels = raw[idx, 7] # extract column 7 for the indexes (idx) from raw dets = [] for bb, s, label in zip(bbox, scores, labels): - dets.append({'bbox': (bb[0], bb[1], bb[2], bb[3]), 'score': s, - 'label': label}) + if label == 1: # only consider pedestrians + dets.append({'bbox': (bb[0], bb[1], bb[2], bb[3]), 'score': s, + 'label': int(label)}) data.append(dets) return data @@ -57,8 +58,8 @@ def save_to_csv(out_path, tracks): """ with open(out_path, "w", newline="") as ofile: - field_names = ['frame', 'id', 'x', 'y', 'w', 'h', 'score', 'wx', 'wy', - 'wz'] + field_names = ['frame', 'id', 'x', 'y', 'w', 'h', 'score', 'label', + 'wy', 'wz'] odict = csv.DictWriter(ofile, field_names) id_ = 1 @@ -71,7 +72,7 @@ def save_to_csv(out_path, tracks): 'w': bbox[2] - bbox[0], 'h': bbox[3] - bbox[1], 'score': track['max_score'], - 'wx': -1, + 'label': track['label'], 'wy': -1, 'wz': -1}