Created
October 15, 2018 12:59
-
-
Save smidm/fc02907a42f87c28c3b985bbb8c676d3 to your computer and use it in GitHub Desktop.
multiple object tracking challenge data file and evaluation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas as pd | |
import errno | |
import numpy as np | |
import sys | |
import warnings | |
def save_mot(filename, df): | |
df.to_csv(filename, header=False, index=False) | |
def load_mot(filename): | |
""" | |
Load Multiple Object Tacking Challenge trajectories file. | |
:param filename: mot filename | |
:return: DataFrame, columns frame and id start with 1 (MATLAB indexing) | |
""" | |
return pd.read_csv(filename, names=[u'frame', u'id', u'x', u'y', u'width', u'height', u'confidence']) | |
def eval_mot(df_gt, df_results, sqdistth=10000): | |
""" | |
Evaluate trajectories by comparing them to a ground truth. | |
:param df_gt: ground truth DataFrame, columns <frame>, <id>, <x>, <y>; <frame> and <id> are 1-based; see load_mot | |
:param df_results: result trajectories DataFrame, format same as df_gt | |
:param sqdistth: square of the distance threshold, only detections and ground truth objects closer than | |
the threshold can be matched | |
:return: (summary DataFrame, MOTAccumulator) | |
""" | |
nan_mask = (df_results.x == -1) | (df_results.x == -1) | df_results.x.isna() | df_results.y.isna() | |
if len(df_results[nan_mask]) > 0: | |
warnings.warn('stripping nans from the evaluated trajectories') | |
df_results = df_results[~nan_mask] | |
from motmetrics.utils import compare_to_groundtruth | |
import motmetrics as mm | |
columns_mapper = {'frame': 'FrameId', 'id': 'Id'} | |
acc = compare_to_groundtruth(df_gt.set_index(['frame', 'id']).rename(columns=columns_mapper), | |
df_results.set_index(['frame', 'id']).rename(columns=columns_mapper), | |
dist='euc', distfields=['x', 'y'], distth=sqdistth) | |
mh = mm.metrics.create() | |
return mh.compute(acc), acc | |
def eval_and_save(gt_file, mot_results_file, out_csv=None): | |
""" | |
Evaluate results and save metrics. | |
:param gt_file: ground truth filename (MOT format) | |
:param mot_results_file: results filename (MOT format) | |
:param out_csv: output file with a summary | |
""" | |
df_gt = load_mot(gt_file) | |
df_results = load_mot(mot_results_file) | |
print('Evaluating...') | |
assert sys.version_info >= (3, 5), 'motmetrics requires Python 3.5' | |
summary, acc = eval_mot(df_gt, df_results) | |
summary['motp_px'] = np.sqrt(summary['motp']) # convert from square pixels to pixels | |
import motmetrics as mm | |
print(mm.io.render_summary(summary)) | |
if out_csv is not None: | |
summary.to_csv(out_csv, index=False) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment