§1The problem
Commercial per-player analysis tools are closed: they don't let you fix mistakes or keep the data. I wanted something similar, but correctable, with the data in my hands.
§2What I built
- ImporterPulls games from match.day automatically (read-only, hard-link copy, every 10 min).
- Analysis pipelinePython: person and ball detection, tracking, linking track fragments, splitting teams by shirt colour.
- Review UIMark the pitch (pixel to metre) and review tracking: merge/split tracks, switch team, undo.
- Who is whoSuggestions based on the shirts: crops of each player are grouped into sheets and read by an AI model.
- NumbersDistance, speed, sprints, heat map, rule-based plays and a player sheet.
- Player filmA video of one player, with the camera following them.
§3The hard parts
5 entries- 01
Keeping each player's identity for 60 minutes
The test had 625 identity switches in 4 minutes; identity is still the weak point.
- 02
Camera model of the panorama
Cylindrical with lens correction, to convert pixels to metres: mean error of 0.8 m with 7 marked points.
- 03
A real bug found by measuring
Timings were off by 0.98 s when the audio started before the video.
- 04
Evaluating with a real metric
HOTA against a public dataset with ground truth, instead of just “looks good”.
- 05
Heavy-job queue on the GPU
One job at a time.
§4Result
- HOTA on the test clip
- 0.42
- recall
- 92%
- precision
- 87%
On the 4-minute test clip with ground truth: HOTA 0.42 (final version), 92% recall and 87% precision. For reference, ByteTrack scores about 0.42 and the 2025 winner 0.60. match.pro has not replaced match.day's analysis yet; that happens once it handles 3 real games end to end.
§5Stack
- Python (PyTorch / CUDA)
- YOLO11
- BoxMOT / BoT-SORT / OSNet
- Node / Next.js 16
- TypeScript
- SQLite
- ffmpeg
- LLM via command-line agent
- pm2
- Tailscale