diff --git a/motmetrics/metrics.py b/motmetrics/metrics.py index 49a789a2..822b27da 100644 --- a/motmetrics/metrics.py +++ b/motmetrics/metrics.py @@ -500,6 +500,44 @@ def num_fragmentations(df, obj_frequencies): simple_add_func.append(num_fragmentations) +def average_overlap(df): + mdf = df.full[(df.full.Type == 'MATCH') | (df.full.Type == 'MISS')] + overlaps = mdf.reset_index().set_index('FrameId')['D'].fillna(0).groupby('FrameId') + return overlaps.agg(np.mean) + + +simple_add_func.append(average_overlap) + + +def num_overlaps(df): + mdf = df.full[(df.full.Type == 'MATCH') | (df.full.Type == 'MISS')] + overlaps = mdf.reset_index().set_index('FrameId')['D'].fillna(0).groupby('FrameId') + return overlaps.count().sum() + + +simple_add_func.append(num_overlaps) + + +def modp(df, average_overlap): + del df + return average_overlap.mean() + + +def modp_m(partials, average_overlap): + del partials + return average_overlap.mean() + + +def moda(df, num_overlaps, num_misses, num_false_positives): + del df + return math_util.quiet_divide(num_misses+num_false_positives, num_overlaps) + + +def moda_m(partials, num_overlaps, num_misses, num_false_positives): + del partials + return math_util.quiet_divide(num_misses+num_false_positives, num_overlaps) + + def motp(df, num_detections): """Multiple object tracker precision.""" return math_util.quiet_divide(df.noraw['D'].sum(), num_detections) @@ -742,6 +780,10 @@ def create(): m.register(partially_tracked, formatter='{:d}'.format) m.register(mostly_lost, formatter='{:d}'.format) m.register(num_fragmentations) + m.register(average_overlap, formatter='{:d}'.format) + m.register(num_overlaps, formatter='{:d}'.format) + m.register(modp, formatter='{:.3f}'.format) + m.register(moda, formatter='{:.3f}'.format) m.register(motp, formatter='{:.3f}'.format) m.register(mota, formatter='{:.1%}'.format) m.register(precision, formatter='{:.1%}'.format) @@ -772,6 +814,8 @@ def create(): 'num_misses', 'num_switches', 'num_fragmentations', + 'modp', + 'moda', 'mota', 'motp', 'num_transfer', diff --git a/motmetrics/tests/test_metrics.py b/motmetrics/tests/test_metrics.py index ec1d0257..59f607f5 100644 --- a/motmetrics/tests/test_metrics.py +++ b/motmetrics/tests/test_metrics.py @@ -369,10 +369,10 @@ def compute_motchallenge(dname): print() print(mm.io.render_summary(summary, namemap=mm.io.motchallenge_metric_names, formatters=mh.formatters)) # assert ((summary['num_transfer'] - summary['num_migrate']) == (summary['num_switches'] - summary['num_ascend'])).all() # False assertion - summary = summary[mm.metrics.motchallenge_metrics[:15]] + summary = summary[mm.metrics.motchallenge_metrics[:17]] expected = pd.DataFrame([ - [0.557659, 0.729730, 0.451253, 0.582173, 0.941441, 8.0, 1, 6, 1, 13, 150, 7, 7, 0.526462, 0.277201], - [0.644619, 0.819760, 0.531142, 0.608997, 0.939920, 10.0, 5, 4, 1, 45, 452, 7, 6, 0.564014, 0.345904], - [0.624296, 0.799176, 0.512211, 0.602640, 0.940268, 18.0, 6, 10, 2, 58, 602, 14, 13, 0.555116, 0.330177], + [0.557659, 0.729730, 0.451253, 0.582173, 0.941441, 8.0, 1, 6, 1, 13, 150, 7, 7, 0.160351, 0.463068, 0.526462, 0.277201], + [0.644619, 0.819760, 0.531142, 0.608997, 0.939920, 10.0, 5, 4, 1, 45, 452, 7, 6, 0.210594, 0.432550, 0.564014, 0.345904], + [0.624296, 0.799176, 0.512211, 0.602640, 0.940268, 18.0, 6, 10, 2, 58, 602, 14, 13, 0.351243, 0.439707, 0.555116, 0.330177], ]) np.testing.assert_allclose(summary, expected, atol=1e-3)