Personal protective equipment detection, running in your browser

A YOLOv8 model trained in 2023 to spot safety equipment on industrial worksites — and, more usefully, to spot when it is missing. It was a desktop application built with PyQt. This is the same model, compiled to ONNX and executed client-side, so the detection happens on your machine rather than on a server.

10
Detected classes
3.0M
Parameters
12 MB
ONNX model

What it looks for

Five items of equipment, each detected in two states. The pair matters: a model that only recognises a helmet tells you nothing useful, because the safety question is whether someone is missing one.

EquipmentPresentAbsent
Helmethelmetno_helmet
Maskmaskno_mask
Jacketjacketno_jacket
Shoeshoeno_shoe
Harnessharnessno_harness

How the detection runs

  1. Letterbox — the frame is scaled to fit 640×640 with its aspect ratio intact and padded with grey, matching what the model saw in training.
  2. Inference — ONNX Runtime Web runs the graph, preferring WebGPU and falling back to multi-threaded WebAssembly. Output is a[1, 14, 8400] tensor: 8400 candidate boxes, each with four coordinates and ten class scores.
  3. Decode — candidates below the confidence threshold are dropped, per-class non-maximum suppression removes duplicate boxes, and the survivors are mapped back out of letterbox space onto the original image.
  4. Draw — boxes are painted on a canvas overlay, green for equipment present and red for equipment missing.

No backend

The server hosting this page only ever sends files. Your camera frames and any image you choose are processed by your own browser and never leave your machine — there is no endpoint for them to be uploaded to. The model is fetched once and cached.

Stack: Next.js static export · ONNX Runtime Web · Caddy on a single EC2 instance.

About the model

Trained during a 2023 internship at HIXAA (Pune) as a real-time PPE detection system. YOLOv8n, 640×640 input, trained for 750 epochs on a custom dataset of 303 annotated industrial-safety images. The original deliverable was a desktop app: a PyQt window with five checkboxes feeding an OpenCV webcam loop. The checkboxes on the live and upload pages here are the same control, ported.

On the numbers. Detection quality was reported at the time as mAP50 0.987 and mAP50-95 0.883 on the internal dataset. Those figures were measured without a held-out validation split — the evaluation set was the training set — so treat them as an upper bound rather than as generalisation performance.

Limitations worth knowing