Detect helmets, vests, and masks in real-time β log every violation, stream live feeds to a web dashboard, and alert your team instantly.
Features Β· Quick Start Β· API Reference Β· Architecture Β· Contributing
Construction sites are among the most hazardous work environments. Manual supervision of PPE compliance is unreliable and resource-intensive. This project automates safety monitoring using YOLOv8 and exposes a production-ready FastAPI backend β supporting multiple camera feeds, a persistent violation log, a live web dashboard, and pluggable alert channels.
| Feature | Description |
|---|---|
| πͺ Helmet Detection | Identifies whether workers are wearing hard hats |
| π¦Ί Vest Detection | Detects high-visibility safety vests |
| π· Mask Detection | Monitors mask compliance on site |
| π§ Person Detection | Tracks worker presence in the frame |
| π Live Counts Overlay | Real-time detection counts on the video feed |
| Feature | Description |
|---|---|
| π REST API | FastAPI backend with full CRUD, streaming, and export endpoints |
| π· Multi-Camera | Webcam, RTSP streams, and video files β unlimited concurrent feeds |
| ποΈ Violation Log | Every violation saved to SQLite (dev) or PostgreSQL (prod) with frame snapshot |
| π‘ Live Dashboard | Bootstrap 5 web UI with MJPEG stream and real-time WebSocket counts |
| π§ Email Alerts | Async SMTP alerts with violation frame attached |
| π Webhook Alerts | HTTP POST to any endpoint (Slack, Teams, custom) |
| π³ Docker | Production-ready Docker + docker-compose with PostgreSQL |
| β Tests & CI | pytest unit + integration tests, GitHub Actions CI pipeline |
# 1. Clone the repo
git clone https://github.com/Ansarimajid/Construction-PPE-Detection.git
cd Construction-PPE-Detection
# 2. Install dependencies
pip install -r requirements/base.txt
# 3. Configure environment
cp .env.example .env
# Edit .env with your email credentials (optional)
# 4. Start the server
uvicorn app.main:app --reloadOpen http://localhost:8000 for the web dashboard, or http://localhost:8000/docs for the interactive API.
cp .env.example .env
# Edit .env with your settings
docker compose upThe full stack starts β FastAPI app + PostgreSQL + persistent violation frame storage. Open http://localhost:8000.
docker compose -f docker-compose.yml -f docker-compose.dev.yml upThe original single-file script still works as before:
conda env create -f yolo_env.yml && conda activate yolo
# or: pip install -r requirements/base.txt
python webcam.pyCopy .env.example to .env and fill in your values:
# Application
APP_ENV=dev
LOG_LEVEL=INFO
# Database (SQLite for dev, PostgreSQL for prod)
DATABASE_URL=sqlite+aiosqlite:///./ppe_detection.db
# Model
MODEL_PATH=Model/ppe.pt
DETECTION_CONFIDENCE=0.5
# Alert timing (seconds)
ALERT_COOLDOWN_SECONDS=10
# Email (Gmail β requires App Password)
SENDER_EMAIL=your_email@gmail.com
RECEIVER_EMAIL=receiver@example.com
EMAIL_PASSWORD=your_app_password
# Optional: generic HTTP webhook
WEBHOOK_URL=https://hooks.example.com/alertsGmail users: Generate an App Password β your regular password won't work with SMTP.
Never commit
.envβ it's already in.gitignore.
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/health |
System health + active camera count |
GET |
/api/v1/metrics |
Per-camera detection counts |
GET |
/api/v1/cameras |
List all cameras |
POST |
/api/v1/cameras |
Add a camera |
POST |
/api/v1/cameras/{id}/start |
Start processing a camera |
POST |
/api/v1/cameras/{id}/stop |
Stop processing a camera |
GET |
/api/v1/violations |
Query violations (filter by camera, date, type) |
GET |
/api/v1/violations/export |
Download violations as CSV |
GET |
/api/v1/stream/{camera_id} |
MJPEG live video stream |
WS |
/api/v1/ws/{camera_id} |
WebSocket: live detection counts (JSON) |
Full interactive docs available at /docs (Swagger UI) and /redoc.
# Add camera
curl -X POST http://localhost:8000/api/v1/cameras \
-H "Content-Type: application/json" \
-d '{"name": "Site Entrance", "source_type": "webcam", "source_uri": "0"}'
# Start it (use the id returned above)
curl -X POST http://localhost:8000/api/v1/cameras/1/start
# Stream in browser
open http://localhost:8000/api/v1/stream/1curl -X POST http://localhost:8000/api/v1/cameras \
-H "Content-Type: application/json" \
-d '{"name": "Gate Camera", "source_type": "rtsp", "source_uri": "rtsp://192.168.1.100/stream"}'βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FastAPI Application β
β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββ β
β β CameraManagerβ β PPEDetector β βViolationCheckerβ β
β β (async tasks)ββββΆβ (YOLOv8) ββββΆβ (per-camera β β
β β per camera β β inference β β state + rules)β β
β ββββββββββββββββ ββββββββββββββββ βββββββββ¬βββββββββ β
β β β
β ββββββββββΌβββββββββ β
β β AlertDispatcher β β
β β ββββββββββββββ β β
β β βEmailHandlerβ β β
β β βWebhookHandlβ β β
β β βDB Handler β β β
β β ββββββββββββββ β β
β βββββββββββββββββββ β
β β
β REST API (/api/v1/*) MJPEG stream WebSocket counts β
β SQLite / PostgreSQL violation_frames/ (filesystem) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Webcam β
source_type: "webcam",source_uri: "0"(device index) - RTSP β
source_type: "rtsp",source_uri: "rtsp://..." - Video file β
source_type: "file",source_uri: "/path/to/video.mp4"
All handlers run concurrently per violation. A failure in one (e.g. SMTP timeout) never blocks the others.
Construction-PPE-Detection/
βββ app/
β βββ main.py # FastAPI app factory + lifespan
β βββ core/
β β βββ config.py # Pydantic settings (all env vars)
β β βββ detector.py # YOLOv8 wrapper
β β βββ violation_checker.py # Business rules, per-camera state
β β βββ frame_annotator.py # Bounding box / overlay drawing
β βββ camera/ # Webcam, RTSP, file sources + manager
β βββ alerts/ # Email, webhook, database handlers
β βββ api/routes/ # REST endpoints
β βββ db/ # SQLAlchemy models + session
β βββ schemas/ # Pydantic request/response models
β βββ static/ # Web dashboard (HTML/JS/CSS)
βββ tests/
β βββ unit/ # Violation checker, dispatcher, config
β βββ integration/ # API endpoint tests
βββ docker/
β βββ Dockerfile # Production image (python:3.11-slim)
β βββ Dockerfile.dev # Dev image with hot-reload
βββ requirements/
β βββ base.txt # Runtime dependencies
β βββ dev.txt # + pytest, ruff
β βββ prod.txt # + gunicorn, asyncpg
βββ docker-compose.yml # App + PostgreSQL (production)
βββ docker-compose.dev.yml # SQLite + hot-reload (development)
βββ pyproject.toml # Ruff config + project metadata
βββ .env.example # Config template (commit this, not .env)
βββ webcam.py # Legacy standalone script
βββ Model/ppe.pt # YOLOv8 weights
pip install -r requirements/dev.txt
pytest tests/ -vTests use an in-memory SQLite database and mock the YOLO model β no webcam or GPU required.
The model detects 10 classes:
| Class | Color |
|---|---|
| Hardhat | Blue |
| Mask | Green |
| NO-Hardhat | Red |
| NO-Mask | Cyan |
| NO-Safety Vest | Magenta |
| Person | Yellow |
| Safety Cone | Purple |
| Safety Vest | Olive |
| Machinery | Teal |
| Vehicle | Gray |
Contributions are welcome! Here's how to get started:
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature - Install dev deps:
pip install -r requirements/dev.txt - Run tests before pushing:
pytest tests/ -v - Commit your changes:
git commit -m 'Add some feature' - Open a Pull Request
See CONTRIBUTING.md for detailed guidelines.
- Python 3.9+
- See
requirements/base.txtfor the full dependency list - Docker + Docker Compose (for containerised deployment)
- A Gmail App Password (for email alerts) β how to generate one
This project is licensed under the MIT License β see the LICENSE file for details.
- Ultralytics YOLOv8 for the detection backbone
- FastAPI for the async web framework
- The open-source computer vision community for datasets and insights
If this project helped you, consider giving it a star β it helps others find it!
