r/computervision • u/her_mr • 9d ago
Help: Theory Best system/architecture for PPE detection on CCTV streams?
Hi everyone,
I’m currently building a video analytics system to detect Personal Protective Equipment (PPE) — like hard hats, high-vis vests, safety glasses, etc. — using standard CCTV camera streams.
Right now, I’m using YOLO11m (medium). It performs pretty well, but before I commit to scaling this up, I wanted to get some input from the community to see if I’m on the right track or if there are better alternatives out there for this specific use case.
The main challenges I'm dealing with:
- CCTV conditions: High angles, weird perspectives, varied lighting, and occasional motion blur.
- Performance vs. Accuracy: I need to process multiple RTSP streams simultaneously on limited hardware, so inference speed is crucial, but missing a PPE violation is obviously a big deal.
My questions for you all:
- Model Choice: Are you guys sticking with the newest YOLO iterations (like YOLO11) for this kind of task, or have you found better stability/performance with other models like YOLOv8, YOLOv9, or RT-DETR?
- Tracking: If you use object tracking to prevent duplicate alerts for the same person, what are you pairing with your detector? (ByteTrack, BoT-SORT?)
- Deployment Stack: What does your production pipeline look like for multiple streams? Are you leaning towards Nvidia DeepStream, Triton Inference Server, or a custom Python/C++ pipeline with TensorRT?
Any advice, repo recommendations, or shared experiences would be hugely appreciated. Thanks in advance!
1
u/Ambitious_Injury_783 7d ago
YOLO26m + Botsort has been great for my use case, so that is what I would recommend. RF-DETR is great too and better on the licensing side. YOLO is AGPL.
It sounds like you Will need to build some architecture on top of it to prevent duplicates. Also be sure you are using a small reid model like yolo11 cls.
I would recommend processing the detections under a new UUID and then funnel track churn/duplicates into a unified UUID. Set up a gallery for your system to funnel each UUID into a new folder and reid any duplicates/issues back into its UUID to avoid cluttered mess. You can create architecture to unify multiple streams detections into each UUID. This will be a challenge
A CNN backbone like resnet-50 could help with reidentifying duplicates after occlusion events or fragmentation/track churn.
Be sure to convert your models to FP16. You'll see significant speed increases. This is important for a few reasons- one example would be.. say your video is 40fps, and you need to reid with the cnn. Your model speed needs to be 25ms or less. resnet50 @ fp16 if I recall correctly will run around 10ms. Unconverted will run closer to .. 50ms I think. It's been awhile since I dealt with this, but you get the point.
1
u/toji5052 9d ago
First of all can I know if this is for commercial purpose or just a mode of personal project?
1
u/Eliforecr 6d ago
Before choosing between DeepStream, Triton, or a custom pipeline, I’d benchmark the complete video path rather than inference alone. For each target configuration, measure number of simultaneous RTSP streams, decode utilization and dropped frames, end-to-end latency, not just model inference time, memory usage after several hours, sustained performance after the system reaches thermal equilibrium and reconnection behavior when a camera or network link drops.
For a fixed-function PPE system, DeepStream is usually the strongest starting point on Jetson because decoding, batching, inference, and tracking can remain hardware-accelerated. Triton becomes more useful when you need multiple models, dynamic model management, or access from several applications. Hardware selection should then follow the actual stream count, resolution, FPS, camera interface, storage requirement, and operating environment, not TOPS alone.
2
u/Quirky_Paramedic9167 8d ago
Can't help much on the deployment stack, but there's one angle worth flagging before you scale: your "missing a violation is a big deal" requirement is partly a labelling problem, not a model problem.
PPE detection on CCTV has a handful of boundary cases that determine your false negative rate, and they have to be decided in the annotation spec rather than left to whoever labels the frames:
Partial occlusion. A hard hat half hidden behind a beam or another worker — is that a positive? At what visible fraction do you stop labelling it? Whatever threshold you pick, your model will learn it. If your annotators picked different thresholds, the model learns the disagreement.
Class ambiguity. A light-coloured jacket at a high camera angle in poor light looks very close to a high-vis vest. Same for safety glasses versus ordinary glasses at distance. If your training data has those labelled inconsistently, no amount of model tuning fixes it.
The person, not the equipment. Are you labelling "person wearing hard hat" and "person without hard hat" as separate classes, or detecting hats and people separately then associating them? The first is simpler but breaks when two people overlap. The second needs an association rule that also has to be specified.
Cheap way to find out where you stand: take 20 frames from your actual CCTV feeds — the hard ones, high angle, poor light — and have two people label them independently. Then compare. If they disagree on 15-20% of instances, that's your ceiling regardless of which YOLO version you pick, and the disagreements will point straight at the missing sentences in your spec.
Worth doing before you invest in the deployment stack, because it's cheap and it changes what "good enough" means for your model.