Teissier YannisDeveloper · AI & fullstackLyon · Sept. 2026
Back to the indexProject 05 of 06
05Case study — 2026

Real-time vision on the edge
a DeepStream pipeline that blurs faces and counts people, built to run on a Jetson

Two TensorRT detectors in series, a tracker that keeps the blur stable, zone counting and a heatmap, all in one GPU pipeline with a live web view, developed on a desktop GPU, written to be carried to a Jetson Orin Nano.

Role
Pipeline, model conversion, Python probes, tooling
Stack
DeepStream 7.1 · TensorRT · GStreamer · Python · ONNX
Status
Working on the dev machine; the Jetson port is prepared, not yet run on hardware

The problem

Cameras in a space raise the same two questions every time: can we count people without recognising them, and can we do it on a small box next to the camera rather than on a server? I wanted a pipeline that answers both: faces made unreadable before any frame leaves the device, people and bags counted in zones, and that runs at video rate on a Jetson-class board.

What I built

A single DeepStream 7.1 pipeline: USB camera, hardware decode into NVMM memory, a YOLO detector for people and bags, then an SCRFD face detector, both as FP16 TensorRT engines, then an NvSORT tracker so a face keeps its ID from frame to frame and the blur does not flicker. A Python probe on the batched frames does the rest: pixelating faces in place, live and total counts, a polygonal zone with entries and exits, a heatmap, and a first "unattended bag" state machine, before the frames are encoded to MJPEG and served by a small stdlib web server with hot-tunable settings, CSV and JSON export.

Getting the face model in took ONNX surgery (a batch dimension added on nine outputs, a fixed input size) and a custom C++ parser; getting frames to Python meant learning which memory types the CPU can see under WSL versus on a Jetson, and switching at runtime. Everything is organised by feature, each one starting with a blocking spike and a fallback, with the business logic (zones, heatmap, luggage, classes) in pure modules tested without GStreamer.

fig. 1 — no screenshot, a drawing
Fig. 1 — one GStreamer pipeline on one GPU · decode, two detectors, tracker, a Python probe that pixelates and counts, MJPEG out01

What I learned

That the dev loop (Windows, WSL2, a USB camera forwarded over usbip, a desktop GPU) is its own project: usbip saturates at 720p and cannot carry raw YUYV, so the honest number is 24.8 fps at 1024×768 on the desktop, and the Jetson figures remain a target until the board is on the desk. That two primary detectors in series beat a detector-plus-cascade for this job. And that the least glamorous choice, a Python probe instead of a C++ plugin, is what made every feature iterable.

“Blur first, count second, and let the tracker decide when a face is still the same face.”
Next — 06RAG chat, multi-cloud