Skip to content

Commit b24e1b0

Browse files
Merge branch 'main' into fix/visibility-bbox
2 parents d75eb0a + 1452979 commit b24e1b0

File tree

8 files changed

+1132
-29
lines changed

8 files changed

+1132
-29
lines changed

tools/tracker/evaluation/Agents.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ Check `harnesses/README.md` for more details
6363
- **TrackEvalEvaluator**: `evaluators/trackeval_evaluator.py`
6464
Wraps TrackEval library, provides tracker output format conversion and delivers state of the art tracking metrics.
6565

66+
- **DiagnosticEvaluator**: `evaluators/diagnostic_evaluator.py`
67+
Per-frame location and distance error analysis between bipartite-matched tracker output tracks and ground-truth tracks. Produces CSV and plot outputs alongside summary scalar metrics (`DIST_T_mean`, `LOC_T_X_mae`, `LOC_T_Y_mae`, `num_matches`).
68+
69+
- **JitterEvaluator**: `evaluators/jitter_evaluator.py`
70+
Measures trajectory smoothness via RMS jerk and acceleration variance, computed from both tracker outputs and ground-truth tracks. Supports GT and ratio variants to isolate tracker-added jitter from dataset-inherent jitter.
71+
6672
Multiple evaluators can be configured in a single YAML pipeline; each runs independently against the same tracker outputs and writes results to its own subfolder under the run output directory.
6773

6874
Check `evaluators/README.md` for more details
@@ -75,6 +81,8 @@ Check `evaluators/README.md` for more details
7581
- Harness: [base/tracker_harness.py](base/tracker_harness.py)
7682
- Evaluator: [base/tracker_evaluator.py](base/tracker_evaluator.py)
7783
- **TrackEval adapter & helpers**: [evaluators/trackeval_evaluator.py](evaluators/trackeval_evaluator.py), [utils/format_converters/](./utils/format_converters.py).
84+
- **Jitter adapter**: [evaluators/jitter_evaluator.py](evaluators/jitter_evaluator.py).
85+
- **Diagnostic adapter**: [evaluators/diagnostic_evaluator.py](evaluators/diagnostic_evaluator.py).
7886

7987
## Guidelines for Adding New Component or Updating Existing One
8088

tools/tracker/evaluation/README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,20 @@ evaluators:
7272
- class: evaluators.trackeval_evaluator.TrackEvalEvaluator
7373
config:
7474
metrics: [HOTA, MOTA, IDF1]
75+
- class: evaluators.diagnostic_evaluator.DiagnosticEvaluator
76+
config:
77+
metrics: [LOC_T_X, LOC_T_Y, DIST_T]
78+
- class: evaluators.jitter_evaluator.JitterEvaluator
79+
config:
80+
metrics:
81+
[
82+
rms_jerk,
83+
rms_jerk_gt,
84+
rms_jerk_ratio,
85+
acceleration_variance,
86+
acceleration_variance_gt,
87+
acceleration_variance_ratio,
88+
]
7589
```
7690
7791
Run the pipeline:
@@ -128,6 +142,14 @@ evaluation/
128142
1. Create a new file in `evaluators/` (e.g., `custom_evaluator.py`)
129143
2. Implement the `TrackerEvaluator` ABC from `base/tracker_evaluator.py`
130144

145+
### Available Evaluators
146+
147+
| Evaluator | Metrics | Description |
148+
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
149+
| `TrackEvalEvaluator` | HOTA, MOTA, IDF1, and more | Industry-standard tracking accuracy metrics via the TrackEval library |
150+
| `DiagnosticEvaluator` | `LOC_T_X`, `LOC_T_Y`, `DIST_T` → summary scalars: `DIST_T_mean`, `LOC_T_X_mae`, `LOC_T_Y_mae`, `num_matches` | Per-frame location and distance error between matched tracker output tracks and ground-truth tracks; uses bipartite (Hungarian) assignment over overlapping frames |
151+
| `JitterEvaluator` | `rms_jerk`, `rms_jerk_gt`, `rms_jerk_ratio`, `acceleration_variance`, `acceleration_variance_gt`, `acceleration_variance_ratio` | Trajectory smoothness metrics based on numerical differentiation of 3D positions; GT and ratio variants allow comparing tracker-added jitter against test-data jitter |
152+
131153
## Canonical Data Formats
132154

133155
The pipeline uses standardized data formats defined by JSON schemas to enable interoperability between components. All implementations must conform to these canonical formats.
@@ -249,7 +271,7 @@ pytest . -v -m integration
249271
pytest tests/ -v # Integration tests
250272
pytest datasets/tests/ -v # Dataset unit tests
251273
pytest harnesses/tests/ -v # Harness unit tests
252-
pytest evaluators/tests/ -v # Evaluators unit tests
274+
pytest evaluators/tests/ -v # Evaluators unit tests
253275
```
254276

255277
**Run tests from a specific file**:

tools/tracker/evaluation/evaluators/README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,91 @@ print(f"Matched pairs: {int(metrics['num_matches'])}")
146146

147147
**Tests**: See [tests/test_diagnostic_evaluator.py](tests/test_diagnostic_evaluator.py) for unit tests covering track matching, scalar metrics, CSV output, and reset workflows.
148148

149+
### JitterEvaluator
150+
151+
**Purpose**: Evaluate tracker smoothness by measuring positional jitter in tracked object trajectories, and compare it against jitter already present in the ground-truth test data.
152+
153+
**Status**: **FULLY IMPLEMENTED** — Computes RMS jerk and acceleration variance from both tracker outputs and ground-truth tracks using numerical differentiation.
154+
155+
**Supported Metrics**:
156+
157+
| Metric | Source | Description |
158+
| ----------------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------- |
159+
| `rms_jerk` | Tracker output | RMS jerk across all tracker output tracks (m/s³) |
160+
| `acceleration_variance` | Tracker output | Variance of acceleration magnitudes across all tracker output tracks (m/s²)² |
161+
| `rms_jerk_gt` | Ground truth | Same as `rms_jerk` computed on ground-truth tracks |
162+
| `acceleration_variance_gt` | Ground truth | Same as `acceleration_variance` computed on ground-truth tracks |
163+
| `rms_jerk_ratio` | Tracker / GT | `rms_jerk` / `rms_jerk_gt` — tracker jitter relative to GT (1.0 = equal) |
164+
| `acceleration_variance_ratio` | Tracker / GT | `acceleration_variance` / `acceleration_variance_gt` — tracker acceleration variance relative to GT (1.0 = equal) |
165+
166+
Comparing `rms_jerk` with `rms_jerk_gt` shows how much jitter the tracker
167+
adds on top of any jitter already present in the test data.
168+
169+
**Algorithm**:
170+
171+
All metrics are derived by applying three sequential layers of forward finite differences to 3D positions, accounting for variable time steps between frames:
172+
173+
$$v_i = \frac{p_{i+1} - p_i}{\Delta t_i}, \quad a_i = \frac{v_{i+1} - v_i}{\Delta t_{v,i}}, \quad j_i = \frac{a_{i+1} - a_i}{\Delta t_{a,i}}$$
174+
175+
- **rms_jerk / rms_jerk_gt**: $\sqrt{\frac{1}{N}\sum |j_i|^2}$ over all jerk samples from all tracks.
176+
- **acceleration_variance / acceleration_variance_gt**: $\text{Var}(|a_i|)$ over all acceleration magnitude samples from all tracks.
177+
- **rms_jerk_ratio / acceleration_variance_ratio**: tracker metric divided by the corresponding GT metric. Returns 0.0 when the GT denominator is zero. Values >1.0 indicate the tracker adds more jitter than is inherent in the ground truth.
178+
179+
Minimum track length: 3 points for acceleration, 4 points for jerk. Shorter tracks are skipped; if no eligible tracks exist, the metric returns 0.0.
180+
181+
For GT metrics, ground-truth frame numbers are converted to relative timestamps using the FPS derived from the tracker output.
182+
183+
**Key Features**:
184+
185+
- Builds per-track position histories from canonical tracker output format.
186+
- Parses MOTChallenge 3D CSV ground-truth file for GT metric computation.
187+
- Supports variable frame rates — time deltas are computed from actual timestamps.
188+
- Deduplicates frames with identical timestamps (mirrors `TrackEvalEvaluator` behaviour).
189+
- Sorts each track's positions by timestamp before metric computation.
190+
- Saves a plain-text `jitter_results.txt` summary to the configured output folder.
191+
192+
**Usage Example**:
193+
194+
```python
195+
from pathlib import Path
196+
from evaluators.jitter_evaluator import JitterEvaluator
197+
198+
evaluator = JitterEvaluator()
199+
evaluator.configure_metrics(['rms_jerk', 'rms_jerk_gt', 'rms_jerk_ratio',
200+
'acceleration_variance', 'acceleration_variance_gt',
201+
'acceleration_variance_ratio'])
202+
evaluator.set_output_folder(Path('/path/to/results'))
203+
204+
# Pass ground_truth=None to skip GT metrics
205+
evaluator.process_tracker_outputs(tracker_outputs, ground_truth=dataset.get_ground_truth())
206+
metrics = evaluator.evaluate_metrics()
207+
208+
print(f"RMS Jerk (tracker): {metrics['rms_jerk']:.4f} m/s³")
209+
print(f"RMS Jerk (GT): {metrics['rms_jerk_gt']:.4f} m/s³")
210+
print(f"RMS Jerk ratio: {metrics['rms_jerk_ratio']:.4f} (1.0 = equal jitter)")
211+
```
212+
213+
**Pipeline Configuration**:
214+
215+
```yaml
216+
evaluators:
217+
- class: evaluators.jitter_evaluator.JitterEvaluator
218+
config:
219+
metrics:
220+
[
221+
rms_jerk,
222+
rms_jerk_gt,
223+
rms_jerk_ratio,
224+
acceleration_variance,
225+
acceleration_variance_gt,
226+
acceleration_variance_ratio,
227+
]
228+
```
229+
230+
**Implementation**: [jitter_evaluator.py](jitter_evaluator.py)
231+
232+
**Tests**: See [tests/test_jitter_evaluator.py](tests/test_jitter_evaluator.py).
233+
149234
## Adding New Evaluators
150235
151236
To add support for a new metric computation library:

tools/tracker/evaluation/evaluators/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
"""Evaluator implementations for tracker evaluation."""
55
from .trackeval_evaluator import TrackEvalEvaluator
66
from .diagnostic_evaluator import DiagnosticEvaluator
7+
from .jitter_evaluator import JitterEvaluator
78

8-
__all__ = ['TrackEvalEvaluator', 'DiagnosticEvaluator']
9+
__all__ = ['TrackEvalEvaluator', 'DiagnosticEvaluator', 'JitterEvaluator']

0 commit comments

Comments
 (0)