Footfall intelligence across a 40-store chain
Existing CCTV turned into a same-day count of entries, dwell and staffing pressure for every branch, without adding a single camera.
- Stores counted every day
- 40+
- Reporting interval
- 15 min
- Video frames leaving the store
- 0
The client
A multi-brand retail group
Named clients are withheld under the confidentiality agreements we work to. Sector, scale and system detail are published with permission.
- Sector
- Retail chains, two brands
- Scale
- 40+ stores across Tamil Nadu and Kerala
- Duration
- 14 weeks to the first ten stores, then a rolling installation
- Team
- Computer vision engineer, Backend engineer, Frontend engineer, Field installation lead, Project manager
What was wrong.
Every branch reported footfall by hand. A guard clicked a tally counter at the door, a manager typed the number into a spreadsheet, and head office compared it with till data a week later. The numbers disagreed with each other often enough that nobody argued from them.
The group already had cameras at every entrance, recording to a local video recorder for security. Nothing read those feeds. The brief was to make existing hardware produce a count head office could act on the same day, without shipping video out of the store and without replacing a camera.
The approach, step by step.
- 01
Survey before code
We pulled a week of recorded footage from six stores across both brands, choosing the worst hours we could find. Doorway glare, monsoon reflections, staff standing in the entrance. That footage became the test set the detector had to pass before anything was installed.
- 02
Detection at the edge
A small fanless box sits beside each recorder and reads the entrance stream. It runs person detection and tracking locally, counts crossings of a line drawn during commissioning, and discards the frame. No video leaves the store.
- 03
One schema for two brands
Each brand had its own store codes and trading hours. We normalised both into a single store dimension, so a regional manager compares like with like and a new branch is a row rather than a migration.
- 04
Reconcile against the till
Counts are joined nightly to point-of-sale receipts to give conversion per store per hour. Where the two disagree by more than a set band, the store is flagged for a camera check instead of being quietly averaged.
- 05
Hand over one screen
Regional managers were trained on a single view: entries, conversion, peak hour and staffing gap. The morning email is generated from the same tables, so there is only ever one version of the number.
The architecture we shipped.
Every layer below exists in the running system. Nothing here is a reference diagram.
- Capture
- Existing dome cameras at each entrance, unchanged, streamed over RTSP from the in-store recorder.
- Edge inference
- One fanless edge box per store running a quantised person detector with multi-object tracking against a commissioned entry line.
- Local buffer
- Counts are written to a queue on the box that survives a broadband drop and replays in order when the link returns.
- Ingest API
- One authenticated endpoint accepts batched counts, deduplicates by store and interval, and rejects readings with clock drift.
- Warehouse
- Quarter-hour intervals in Postgres, aggregated nightly into store-hour and store-day tables joined to point-of-sale receipts.
- Reporting
- A web dashboard and a scheduled morning email, both reading the same aggregate tables rather than their own queries.
- Monitoring
- Each box sends a heartbeat every five minutes. A silent store raises a ticket before a manager notices the number is missing.
What it does now.
Read from the system itself. No revenue claims, no multiples.
Stores counted every day
Every entrance line, every trading hour, with no manual tally.
Reporting interval
Counts land in quarter-hour buckets instead of a weekly spreadsheet.
Video frames leaving the store
Only counts cross the network; frames are discarded at the edge.
Heartbeat from every site
A camera or link failure raises a ticket the same morning.
What it runs on.
- Python
- OpenCV
- ONNX Runtime
- RTSP / NVR integration
- FastAPI
- PostgreSQL
- Next.js dashboard
- Docker
- Grafana
The count stopped being an argument. The Monday meeting is now about what to do with the number, not whether it is right.
Attributed by role and sector only, at the client's request.
What happens next.
Dwell heatmaps for two flagship stores, and a staffing suggestion that reads the same hourly table rather than a separate model.
Services behind this build
Sector
Retail & Malls40+ stores across Tamil Nadu and Kerala. The pattern transfers; the domain detail is rebuilt for every client.
Have a system that should work like this one?
We will walk your process, tell you what is worth automating, and scope the first version that can be measured.