Note: AI-assisted coding tools were used for minor implementation support
Real-time violence detection on edge devices
- 50 FPS on Raspberry Pi 5
- 81% accuracy on RWF2000
- 0.88 ROC-AUC
- Cross-dataset evaluation (RLVS / Hockey / Movies)
Watch demo here: https://youtu.be/Z1gKG_AFHuk
This project presents a lightweight violence detection system designed for real-time deployment on CPU-based edge devices.
The system combines spatial detection and temporal analysis:
- YOLO localizes potential violence regions
- A temporal classifier analyzes frame sequences to detect violent behavior
The goal is to achieve reliable violence detection while maintaining high inference speed on low-power hardware such as Raspberry Pi.
- Spatial Detection: YOLO26 for real-time object detection and localization
- Multi-Object Tracking: Tracker with confidence-based hysteresis
- Temporal Classification: Temporal classifier on 8-frame feature sequences
- Robust Tracking: Automatic tracker failure recovery and confidence decay
- Real-time Performance: Optimized for CPU and GPU inference
- Adaptive Frame Sampling: Configurable detection intervals for efficiency
git clone https://github.com/NgMQuang/Lightweight-YOLO-based-real-time-violence-detection-on-CPU
cd Lightweight-YOLO-based-real-time-violence-detection-on-CPU
pip install -r requirements.txt
Download weights and place them inside:
ViolenceDetector/
├── violence_yolo.onnx
├── temporal_classifier.onnx
├── temporal_classifier.onnx.data
└── demo.mp4
Also place a demo.mp4 file in the folder for testing.
cd ViolenceDetector
python ViolenceDetection.py
Training metrics
- Classifier
| Metric | Score |
|---|---|
| Accuracy | 0.8125 |
| Precision | 0.7990 |
| Recall | 0.8350 |
| F1 Score | 0.8166 |
| Specificity | 0.7900 |
| False Positive Rate (FPR) | 0.2100 |
| False Negative Rate (FNR) | 0.1650 |
| ROC–AUC | 0.8861 |
- Suspicious area localization
| Class | Images | Instances | Box(P - R - mAP50 - mAP50-95) |
|---|---|---|---|
| all | 3000 | 2865 | 0.712 - 0.704 - 0.754 - 0.425 |
To evaluate generalization ability, the model was tested on other datasets WITHOUT TRAINING ON THEM.
| Metric | RLVS | HKF | Movies |
|---|---|---|---|
| Accuracy | 0.7655 | 0.8090 | 0.7463 |
| Precision | 0.7010 | 0.7388 | 0.8182 |
| Recall | 0.9260 | 0.9560 | 0.6300 |
| F1 Score | 0.7979 | 0.6620 | 0.7119 |
| Specificity | 0.6050 | 0.7900 | 0.8614 |
| False Positive Rate (FPR) | 0.3950 | 0.3380 | 0.1386 |
| False Negative Rate (FNR) | 0.0740 | 0.0440 | 0.3700 |
| ROC–AUC | 0.9037 | 0.9247 | 0.8574 |
Average FPS: 51.74
Pipeline timing:
| Task | Average(ms) | Min(ms) | Max(ms) |
|---|---|---|---|
| Detection | 10.426 | 0.000 | 165.764 |
| Tracking | 2.118 | 0.000 | 14.342 |
| Classifier | 0.542 | 0.000 | 15.600 |
| Visualization | 0.683 | 0.284 | 43.064 |
| Frame latency | 19.327 | 4.006 | 171.141 |
https://drive.google.com/drive/folders/10E4KqX_fWGagm4lv79oJ9eFl63tIdKg7?usp=drive_link
or you can find in releases
FPS_VIDEO = 30 # Video frame rate, auto read when assign video path
TOTAL_TIME_DETECT = 2.5 # Detection window (seconds), DO NOT CHANGE
FRAME_PER_DETECT = 8 # Frames per classifier input, DO NOT CHANGE
DETECT_INTERVAL = 10 # Automatically computed by the implementation.
TRACKER = "MEDIANFLOW" # Tracker type, support MOSSE and KCF
MAX_TRACKS = 5 # Max simultaneous tracks, DO NOT CHANGE
CONF_ON = 0.25 # Show track threshold
CONF_OFF = 0.1 # Hide track threshold
STICK_WEIGHT = 0.7 # Stickiness in scoring
alpha = 0.8 # EMA smoothing factor
TRACKER_FAILURE_DECAY = 0.5 # Confidence decay on failure- YOLO detects suspicious areas
- Returns bounding boxes with confidence scores
- Extracts feature vectors
- Tracker updates box positions frame-to-frame
- Confidence scores decay if tracker fails
- Boxes with low confidence are removed
- Collects last 8 feature vectors
- Passes to temporal classifier
- Outputs violence probability (0.0 - 1.0)
- Alerts if probability > 0.8
- Tracks shown/hidden based on confidence thresholds
- Color-coded bounding boxes with track IDs
- Violence probability displayed on frame
- Input: 256×320 RGB images (normalized 0-1)
- Output:
- Detections: (5, 6) - up to 5 boxes with [x1, y1, x2, y2, conf, class]
- Features: (896, 15) - feature vector for temporal analysis
- Inference Time: ~50-200ms (CPU)
- Input: (8, 896, 15) - 8 consecutive feature vectors
- Output: (2) - logit for binary classification [1] for fight and [0] for non-fight
- Inference Time: ~1-5ms (CPU)
The script displays:
- Bounding boxes around detected people
- Track IDs and confidence scores
- Tracker status ("OK" or "HOLD")
- Violence probability when classified
- Alert when violence confidence > 0.8
Models trained on custom dataset derived from RWF2000 (Real World Fighting Dataset):
- Contains real-world violence/non-violence scenarios
- Custom labeling
- 0.75 mAP on detection task
- 81.25% accuracy on violence classification
Dataset used for testing:
- Hockey Fight
- Movie Fight
- RLVS
- Improve spatial feature extraction
- Optimize for embedded deployment
- YOLO26: https://github.com/ultralytics/ultralytics
- ONNX Runtime: https://onnxruntime.ai/
- RWF2000 Dataset: https://github.com/mchengny/RWF2000-Video-Database-for-Violence-Detection
MIT License
- YOLO26 by Ultralytics
- RWF2000 dataset creators
- ONNX Runtime community
- Hockey Fight
- Movie Fight
- RLVS





