3 * mtp is the ``Multi Tracked Paths'', an implementation of the
4 * k-shortest paths algorithm for multi-target tracking.
6 * Copyright (c) 2012 Idiap Research Institute, http://www.idiap.ch/
7 * Written by Francois Fleuret <francois.fleuret@idiap.ch>
9 * This file is part of mtp.
11 * mtp is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 3 as
13 * published by the Free Software Foundation.
15 * mtp is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 * License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with selector. If not, see <http://www.gnu.org/licenses/>.
32 #include "mtp_tracker.h"
34 //////////////////////////////////////////////////////////////////////
36 scalar_t noisy_score(scalar_t true_score, scalar_t erroneous_score,
37 scalar_t score_noise, scalar_t flip_noise) {
38 if(drand48() < flip_noise) {
39 return erroneous_score + score_noise * (2.0f * scalar_t(drand48()) - 1.0f);
41 return true_score + score_noise * (2.0f * scalar_t(drand48()) - 1.0f);
45 void create_light_test(MTPTracker *tracker) {
47 int nb_time_steps = 8;
48 int motion_amplitude = 1;
50 tracker->allocate(nb_time_steps, nb_locations);
52 // We define the spatial structure by stating what are the possible
53 // motions of targets, and what are the entrances and the exits.
55 // Here our example is a 1D space with motions from any location to
56 // any location less than motion_amplitude away, entrance at
57 // location 0 (or in the first time frame, i.e. targets can already
58 // be in the scene when the sequence starts) and exit at location
59 // nb_locations-1 (or from the last time frame, i.e. targets can
60 // still be present when the sequence finishes)
62 for(int l = 0; l < nb_locations; l++) {
63 for(int m = 0; m < nb_locations; m++) {
64 tracker->allowed_motions[l][m] = abs(l - m) <= motion_amplitude;
68 for(int t = 0; t < nb_time_steps; t++) {
69 for(int l = 0; l < nb_locations; l++) {
70 // We allow targets to enter in the first time frame, or in
72 tracker->entrances[t][l] = (t == 0 || l == 0);
73 // We allow targets to leave from the last time frame, or from
74 // location nb_locations-1
75 tracker->exits[t][l] = (t == nb_time_steps - 1 || l == nb_locations-1);
79 // We construct the graph corresponding to this structure
81 tracker->build_graph();
83 // Then, we specify for every location and time step what is the
84 // detection score there.
86 scalar_t flip_noise = 0.05f;
87 scalar_t score_noise = 0.0f;
89 // We first put a background noise, with negative scores at every
92 for(int t = 0; t < nb_time_steps; t++) {
93 for(int l = 0; l < nb_locations; l++) {
94 tracker->detection_scores[t][l] = noisy_score(-1.0, 1.0, score_noise, flip_noise);
98 // Then we add two targets with a typical tracking local minimum
100 // * Target A moves from location 0 to the middle, stays there for a
101 // while, and comes back. It is strongly detected on the first
104 // * Target B moves from location nb_locations-1 to the middle, stay
105 // there for a while, and comes back. It is strongly detected on
108 int la, lb; // Target locations
109 scalar_t sa, sb; // Target detection scores
110 for(int t = 0; t < nb_time_steps; t++) {
111 if(t < nb_time_steps/2) {
113 lb = nb_locations - 1 - t;
114 sa = noisy_score(10.0, -1.0, score_noise, flip_noise);
115 sb = noisy_score( 1.0, -1.0, score_noise, flip_noise);
117 la = nb_time_steps - 1 - t;
118 lb = t - nb_time_steps + nb_locations;
119 sa = noisy_score( 1.0, -1.0, score_noise, flip_noise);
120 sb = noisy_score(10.0, -1.0, score_noise, flip_noise);
123 if(la > nb_locations/2 - 1) la = nb_locations/2 - 1;
124 if(lb < nb_locations/2 + 1) lb = nb_locations/2 + 1;
126 tracker->detection_scores[t][la] = sa;
127 tracker->detection_scores[t][lb] = sb;
130 { // Write down the tracker setting, so that we can use it as an
131 // example for the mtp command line
132 ofstream out_tracker("tracker.dat");
133 tracker->write(&out_tracker);
137 void create_heavy_test(MTPTracker *tracker) {
138 int nb_locations = 100;
139 int nb_time_steps = 1000;
141 tracker->allocate(nb_time_steps, nb_locations);
143 for(int l = 0; l < nb_locations; l++) {
144 for(int m = 0; m < nb_locations; m++) {
145 tracker->allowed_motions[l][m] = (drand48() < 0.1);
149 for(int t = 0; t < nb_time_steps; t++) {
150 for(int l = 0; l < nb_locations; l++) {
151 tracker->entrances[t][l] = drand48() < 0.01;
152 tracker->exits[t][l] = drand48() < 0.01;
156 tracker->build_graph();
158 for(int t = 0; t < nb_time_steps; t++) {
159 for(int l = 0; l < nb_locations; l++) {
160 tracker->detection_scores[t][l] = scalar_t(drand48()) - 0.95f;
165 int main(int argc, char **argv) {
170 } else if(argc == 2 && strcmp(argv[1], "stress") == 0) {
173 cerr << "mtp_examples [stress]" << endl;
177 MTPTracker *tracker = new MTPTracker();
180 create_heavy_test(tracker);
182 create_light_test(tracker);
185 // Performs the tracking per se
189 // Prints the detected trajectories
191 for(int t = 0; t < tracker->nb_trajectories(); t++) {
192 cout << "Trajectory "
194 << " starting at " << tracker->trajectory_entrance_time(t)
195 << ", duration " << tracker->trajectory_duration(t)
196 << ", score " << tracker->trajectory_score(t)
197 << ", through locations";
198 for(int u = 0; u < tracker->trajectory_duration(t); u++) {
199 cout << " " << tracker->trajectory_location(t, u);