Skip to Content

Shoplifting Detection (R&D)

R&D Spike: Real-Time Shoplifting Detection with YOLO Pose and a Custom Model
25 September 2026 by

Client: International Salon Supplies (internal R&D)

Role: Engineer (research & prototype)

Period: Mar 2026

Status: Prototype

Tech stack: Python 3.12, Ultralytics YOLO, ByteTrack, PyTorch (CUDA), OpenCV, WebSockets, Next.js 16, React 19, Tailwind CSS, WebRTC, Roboflow

A proof of concept that runs in-store CCTV streams through computer vision to flag possible concealment behaviour in real time. It fuses a custom-trained detector with explainable pose-based rules and per-person temporal filtering, and shows results as a live overlay on a multi-camera dashboard.

Why

Retail shrinkage is a real cost for any store. I wanted to find out, quickly and cheaply, whether off-the-shelf computer vision could give staff a useful early signal from the cameras the store already has. This was a time-boxed spike, not a product.

Architecture

CCTV streams ─► frame-grabber thread per camera (buffer = 1, always the latest frame)
                   │
                   ▼
   AI thread per camera
   ├─ pose model + ByteTrack → stable person IDs
   ├─ custom shoplifting detector → boxes matched to people (IoU ≥ 0.30, 3 consecutive frames)
   ├─ 5 pose rules scaled to torso height
   ├─ 8-frame temporal filter per person; long dwell → "loitering"
   └─ JSON metadata (normalised boxes, status, alert) ─► WebSocket
                                                            │
Next.js dashboard: camera grid (WebRTC video) + positioned person markers,
red alert badges, click to go fullscreen

Engineering highlights

Two signals are better than one

A learned detector alone produces opaque false positives. Hand-written rules alone miss too much. The prototype combines both:

  • A custom YOLO detector trained on a public, CC-BY dataset (two classes: normal and shoplifting) for 100 epochs.
  • Five explainable pose rules: hand to pocket, wrist below hip (bag), hand at torso centre (jacket), crouching, and an under-arm tuck. Every threshold is a ratio of torso height, not a pixel value, so the rules work at any distance from the camera.

A detection only matters if it's matched to a tracked person for three consecutive frames. Each person then has an eight-frame history that smooths out single-frame noise.

Low latency by design

Each camera has a grabber thread with a one-frame buffer, so inference always runs on the latest frame and never falls behind. Video goes to the browser over WebRTC, and AI results travel separately as lightweight WebSocket metadata. The dashboard never decodes frames for inference, and the model never waits on the UI.

Honest results

Validation on the training dataset reached precision ≈ 0.76, recall ≈ 0.67, mAP50 ≈ 0.65. That's encouraging for a spike and nowhere near enough to act on without a human in the loop.

What production would need

  • Evaluation on real in-store footage, not a public dataset
  • A privacy and legal review, clear signage, and data-retention rules
  • A human-review workflow: alerts are prompts for staff attention, never accusations
  • Proper per-camera calibration and monitoring for false-positive rates

By the numbers

  • ~400 lines of Python, ~380 lines of TypeScript/React
  • Multiple concurrent camera streams on a single CUDA GPU
  • Built across a handful of focused sessions in March 2026

Takeaway

A short, well-scoped spike answered the question: yes, the building blocks work. It also produced a clear list of what it would take to do this responsibly, which is at least as valuable as the demo.