RaceRecap
A Windows application that watches a race finish line through one or more cameras, reads bib numbers, records crossing times and puts every uncertain case in front of the operator.
This project is being built. What is shown is current, not final.

- Client
- PRESEO Digital
- In-house product
- Services
- SoftwareAI automationUX/UIIntegrations
- Built with
- Python, PyTorch, Ultralytics YOLO, EasyOCR, CUDA, Electron, React, TypeScript, Tailwind CSS, Vite, RTSP
Overview
RaceRecap turns ordinary cameras into a finish-line timing system. It detects runners as they approach the line, reads their bib numbers from QR codes or printed digits, records the moment each one crosses, and keeps the photographic evidence behind every result. It runs entirely on a laptop at the event, with no internet connection required. The product is built and maintained in-house by PRESEO Digital and is currently in development.
The challenge
Timing a race accurately is not one problem but four, and they interfere with each other. A runner has to be detected, identified, timed and then reconciled against every other camera that saw the same crossing. Identification is the part that fails most often: a bib can be obscured by an arm, a crowd, motion blur or low light. Most systems treat a failed read as a failed result, which means a real finisher disappears. Cameras also drift, get bumped and fall out of sync with one another, and a system that hides that drift produces results nobody can defend afterwards.
What PRESEO did
The system was built around one rule: a finish time is stored even when identification fails. Detection, bib reading and crossing detection are separate stages, so an unidentified crossing becomes a timed record awaiting a name rather than a lost one. Person detection runs on a YOLO model through PyTorch, using an NVIDIA GPU when CUDA is available and falling back to the processor automatically when it is not. Bib identification combines QR decoding with printed-number OCR. Each camera gets its own calibrated finish wall, or several cameras share one surveyed finish plane, and duplicate sightings of the same runner are fused into a single finish instead of several. Anything the system is unsure about — an unreadable bib, a possible duplicate, a camera that appears to have moved — is raised as a review item or an integrity finding rather than quietly resolved. The operator console, races workspace, results, review, integrity and calibration screens are a React interface running in Electron over the Python pipeline, and the whole thing ships as a self-contained Windows installer that carries its own Python runtime, AI models and C++ redistributable.
What was delivered
- Live operator console with program monitor, race clock and signal diagnostics
- Person detection on a YOLO model with automatic GPU or CPU execution
- Bib identification by QR decoding and printed-number OCR
- Per-camera finish walls and a surveyed shared finish plane
- Crossing detection that stores a time even when the bib cannot be read
- Multi-camera fusion so one runner produces one finish
- Race creation, categories, custom fields and CSV participant import
- Review queue for uncertain identities and duplicate candidates
- Integrity findings for camera movement and synchronisation drift
- Durable evidence images attached to every crossing
- Crash-recoverable result storage
- Self-contained Windows installer requiring no administrator rights
Key features
A time is never lost
Timing and identification are separate stages. If the bib cannot be read, the crossing is still recorded and waits for a name instead of vanishing.
Two ways to read a bib
QR decoding handles coded bibs; OCR reads printed numbers. Both feed the same identification record, so either can carry a result.
One runner, one finish
When several cameras see the same crossing, the observations are fused into a single result rather than appearing as duplicate finishers.
Uncertainty is shown, not hidden
Unreadable bibs and likely duplicates go to a review queue. Camera movement and clock drift are raised as integrity findings the operator must resolve.
Evidence behind every result
Each crossing keeps its own images, so a disputed placing can be checked after the event instead of argued from memory.
Runs on the laptop at the finish
Detection, OCR and storage are local. An NVIDIA GPU makes it faster; a machine without one still runs correctly. Cloud OCR is opt-in, never assumed.
Screens






Next step