Turns the CCTV cameras a restaurant or shop already has into live operational numbers, without identifying anyone.
Chains have cameras in every branch, but nobody watches them. BranchSight watches the feeds continuously and answers the questions a branch manager actually asks: how many people came in, how long the queue is, whether the counter has been left empty, and where customers spend their time.
Counts people crossing a line drawn across the door, in each direction, minute by minute.
Measures how many people are waiting at the counter and how long they waited. Raises an alert if the queue stays too long.
Alerts when nobody has been behind the counter for a set time during opening hours. It checks presence, never who.
Shows which parts of the floor people spend time in and the average time spent in each zone.
Each camera has its own worker. It always takes the newest frame, so delay never builds up. It finds people, follows each one across frames with a temporary ID, updates the counts, and pixelates faces before the frame goes to the browser. Only per-minute numbers and alert events are saved.
Every number here comes from a script in the repository and can be re-run. The weak results are reported along with the strong ones.
MOT17 is the standard public benchmark for following people in video, with every person hand-annotated. The system was run on all 7 training sequences and scored with an evaluator that matches the official TrackEval rules. The detector is the off-the-shelf nano model; it was not trained on this data.
Almost all errors are missed people (82,559 missed boxes against 2,299 false alarms), mostly small and distant figures in crowded scenes. Giving the model more pixels helps more than a bigger model, but costs 2.3x the compute. On the shop-entrance sequence the default setup scores MOTA 56.4.
Instead of counting by hand, the true number of line crossings was computed by running the same counting code over the benchmark's annotated tracks. That gave 76 real crossings on 8 lines across the three fixed-camera sequences.
| Setup | Crossings counted (true: 76) | Total error |
|---|---|---|
| Nano model, 640 px (default) | 50 | -34% |
| Small model, 640 px | 69 | -9% |
| Nano model, 960 px | 74 | -3% |
At 960 px the total is close, but individual lines are still off in both directions, so per-line accuracy is lower than the total suggests. The sample is small.
| Hardware | Setup | Time per frame (median) |
|---|---|---|
| Laptop CPU (AMD Ryzen AI 9 HX 370) | PyTorch, detection only | 51.1 ms |
| Laptop CPU | ONNX Runtime, detection only | 29.0 ms |
| Laptop CPU | Full pipeline, one camera | 44.4 ms (21.9 FPS) |
| Laptop GPU (RTX 5070 Ti) | PyTorch, network only, 1 frame | 18.9 ms |
| Laptop GPU | PyTorch, network only, 3 cameras batched | 9.0 ms per frame |
| Cloud VM (2 shared vCPUs) | Full pipeline, one camera | 274 ms (3.2 FPS) |
Demo footage: MOT17 sequences from MOTChallenge (CC BY-NC-SA 3.0, non-commercial) and a Pexels stock clip, both with faces pixelated. The code is AGPL-3.0 because it uses Ultralytics YOLO.