Freelance project
CCTV Surveillance
- Problem
- Nobody can watch a camera feed all the time, so loitering, an abandoned bag, a fight or a fire is often noticed only after the fact.
- Approach
- YOLOv8n, MediaPipe pose rules and a custom 3D-CNN on 20-frame clips analyse the feed, a colour heuristic checks for fire, and a rules engine with cooldowns turns all of it into events that are emailed with a snapshot.
- Result
- A Flask app that watches a live camera or an uploaded video, raises five kinds of events, and can be retuned from its dashboard while it runs.
- My role
- Freelance AI engineer (2024–2025). Built the system end to end for a client: data pipeline, models, training and app.
- Stack
- Python
- OpenCV
- YOLOv8n (Ultralytics)
- MediaPipe Pose
- TensorFlow / Keras (3D-CNN)
- Flask
- SMTP email
- Links
Code private (client work)
01
Architecture
- Video source: a camera picked in the dashboard, or an uploaded video file. Connecting to a camera runs in a background thread with a timeout, so a camera that does not answer does not freeze the app.
- YOLOv8n, the smallest YOLOv8 model, detects people and objects in each frame; it was picked for speed, since it runs on every frame.
- MediaPipe Pose runs on each detected person's box and extracts body keypoints; hand-written rules on those keypoints flag attacking and violent poses.
- 3D-CNN: a custom 3D convolutional network looks at a sliding window of 20 frames, so it sees motion over time, and scores the clip for violence.
- Fire check: a colour heuristic, not a trained model. The frame is converted to HSV and masked for fire-like colours; if enough of the frame matches, the matching regions become a fire event with a confidence.
- Rules engine: the outputs become events: loitering (a person staying within a small area for too long), unattended objects (an object present for a long time with no person nearby), altercation (attack or violence signals above a confidence threshold), violence, and fire. Each event type has its own cooldown, so one incident does not send a stream of alerts.
- Email alert: when email alerts are switched on, each event is sent by SMTP with the frame that triggered it attached.
- Flask dashboard: streams the annotated video, lists alerts, and lets the operator change thresholds, cooldowns and other settings while the system runs; changes are applied in the background without a restart.
02
Key decisions
A rules engine on top of the models, with cooldowns
Rules such as "same person in the same small area for too long" are easy to explain to whoever receives the alert and easy to tune, and per-type cooldowns stop alert floods. The cost is hand-picked thresholds: they need tuning for each camera, and anything the rules do not describe is never flagged.
Clips, not single frames, for violence, with pose rules as a second signal
A single frame of two people close together can look like a hug or a fight; 20 frames give the 3D-CNN the motion that tells them apart, and the pose rules add a separate keypoint-based signal. The cost is latency (the clip buffer must fill before it is scored) and more computation than a per-frame classifier.
A colour heuristic for fire instead of a trained detector
Masking fire-like colours in HSV needs no fire training data and costs almost nothing per frame. The cost is false alarms on anything orange or red and bright, such as lamps or sunsets, and missed fires that do not show open flame; it is a rough first check, not a fire detector.
03
Results
- The rules engine raises altercation and violence events from the model outputs and fire events from the colour heuristic; the loitering and unattended-object rules exist but are unreliable without tracking (see next steps).
- When email alerts are on, every event is emailed with the triggering frame attached; per-type cooldowns keep one incident from producing a stream of emails.
- Works on a live camera or an uploaded video, and settings changed in the dashboard take effect while it runs.
04
What I'd do next
- Build a labelled set of recorded footage and measure precision and recall per event type; no accuracy figures are reported for this project.
- Add a multi-object tracker. As built, the loitering and unattended-object rules match detections frame by frame without tracking identity, so they fire unreliably; a tracker would let them follow the same person or object over time.
- Replace the fire colour heuristic with a detector trained on fire and smoke images.