shiroyaparth/fight_detection
GitHub: shiroyaparth/fight_detection
一个基于 YOLOv8、DeepSORT 与 MediaPipe 的规则驱动型实时人群暴力检测系统,通过融合移动速度、边界框重叠和手臂姿态三条行为规则识别异常并自动触发警报。
Stars: 0 | Forks: 0
# 人群监控异常检测系统





## 概述
该系统逐帧处理视频画面,检测并跟踪场景中的每一个人,并应用三条独立的行为规则来实时识别暴力或攻击性活动。当触发警报时,屏幕会显示红色边界框和横幅,系统还会自动保存一段事件前录像供后续查看——包括警报触发前 2 秒的画面。
本项目作为大学第六学期的课程项目开发,未进行自定义模型训练。所有组件均使用预训练的开源模型。
## 结果
在 Real-Life Violence Situations Dataset 的 50 个标注视频片段(25 个暴力,25 个非暴力)上进行了评估。
| 指标 | 数值 |
|---|---|
| 检出率 (Recall) | **80%** |
| 误报率 | **4%** |
| 总体准确率 | **88%** |
| 真阳性 | 20 / 25 |
| 假阴性 | 5 / 25 |
| 真阴性 | 24 / 25 |
| 假阳性 | 1 / 25 |
| 处理速度 (GPU) | 15 – 75 FPS |
| 处理速度 (CPU) | 5 – 10 FPS |
## 工作原理
每一帧视频画面都会经过一个 4 阶段的 pipeline:
```
Video Input
│
▼
YOLOv8 Nano ──────── detects all persons → [x1,y1,x2,y2,conf]
│
▼
DeepSORT Tracker ─── assigns persistent IDs, stores 10-frame position history
│
▼
PoseAnalyzer ─────── evaluates 3 rules per person per frame
│ ├── Rule 1: Velocity > 15 px/frame (rolling 5-frame avg)
│ ├── Rule 2: IoU Overlap > 0.20 with any other person
│ └── Rule 3: Wrist above shoulder (MediaPipe landmarks)
│
▼
Alert Logic ──────── fires if: velocity AND (overlap OR pose)
requires 3 consecutive frames before alerting
│
▼
Output: annotated video + alert banner + auto-saved incident clips
```
### 3 条检测规则
**规则 1 — 速度**
测量每个被跟踪人员的移动速度。通过 5 帧滚动平均值消除跟踪抖动。速度超过 15 px/帧即表示具有攻击性动作。
**规则 2 — 边界框重叠度 (IoU)**
测量两个人的边界框共享面积是否超过二者总面积的 20% —— 这通常与扭打或直接肢体接触一致。
**规则 3 — 手臂抬起 (MediaPipe Pose)**
检查手腕关键点在图像坐标系中是否位于对应肩膀的上方。要求关键点可见度 > 0.5 才会触发。
**警报融合**
```
alert = velocity_flag AND (overlap_flag OR pose_flag)
```
将速度作为强制条件,消除了大部分因人员单纯靠近或出于非暴力原因抬起手臂而产生的误报。
**时序平滑**
只有当同一人连续 3 帧或以上触发条件时才会激发警报。单帧检测到的伪影会被静默忽略。
## 功能
- **实时处理** —— 支持视频文件、网络摄像头或任何 RTSP 流
- **黄色骨架叠加** —— 为每个人绘制身体关节和肢体连线
- **颜色编码的边界框** —— 绿色(正常)/ 红色(警报)
- **事件前录像保存** —— 每次警报触发前 2 秒 + 后 3 秒的画面,自动保存至 `alert_clips/`
- **结构化日志** —— 每次警报均记录时间戳、人员 ID、具体规则数值以及连续帧数
- **GPU 加速** —— YOLO 运行在 CUDA 上;MediaPipe 运行在 CPU 上
- **批量评估** —— 独立的 `evaluate.py` 脚本,用于在标注视频集上测量 TP/FP/TN/FN
- **模块化架构** —— 每个组件均可独立替换
## 项目结构
```
fight_detection/
│
├── main.py # Main pipeline, clip saver, alert logger
├── detector.py # YOLOv8 wrapper — person detection
├── tracker.py # DeepSORT wrapper — persistent ID tracking
├── pose_analyzer.py # 3 behavioral rules + MediaPipe pose
├── visualizer.py # Skeleton drawing, bounding boxes, alert banner
├── config.py # All thresholds in one place
├── evaluate.py # Batch evaluation on labelled clip sets
│
├── pose_landmarker_lite.task # MediaPipe model file (download separately)
├── requirements.txt
│
├── output_annotated.mp4 # Annotated output video (auto-created)
├── detection_log.txt # Per-alert log (auto-created)
├── evaluation_results.txt # Evaluation metrics (auto-created)
└── alert_clips/ # Auto-saved incident clips
├── alert_1.mp4
├── alert_2.mp4
└── ...
```
## 环境要求
### 硬件
- CPU: Intel i5 / Ryzen 5 或更高
- 内存: 推荐 8 GB
- GPU: 支持 CUDA 的 NVIDIA GPU(可选,但推荐使用 —— RTX 3050 或更高)
- 存储: 模型和库约需 ~3 GB
### 软件
- Windows 10 / 11(在 Windows 11 上测试)
- Python 3.10 或 3.11
- 支持 CUDA 12.x 的 NVIDIA 驱动程序(用于 GPU 加速)
## 安装说明
### 1. 克隆代码库
```
git clone https://github.com/yourusername/fight-detection.git
cd fight-detection
```
### 2. 创建并激活虚拟环境
```
# Windows
python -m venv venv
venv\Scripts\activate
# Mac / Linux
python -m venv venv
source venv/bin/activate
```
### 3. 安装依赖
```
pip install -r requirements.txt
```
或手动安装:
```
pip install ultralytics mediapipe==0.10.32 opencv-python numpy deep-sort-realtime
```
### 4. 安装支持 GPU 的 PyTorch(推荐)
```
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
```
验证 GPU 是否可用:
```
python -c "import torch; print('CUDA:', torch.cuda.is_available())"
```
### 5. 下载 MediaPipe 姿态模型
在浏览器中打开此链接并将文件保存到项目根目录:
```
https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/pose_landmarker_lite.task
```
该文件必须命名为 `pose_landmarker_lite.task`,并放置在项目根目录下。
## 使用说明
### 在视频文件上运行
打开 `main.py` 并设置视频路径:
```
VIDEO_PATH = r"C:\path\to\your\video.mp4"
cap = cv2.VideoCapture(VIDEO_PATH)
```
然后运行:
```
python main.py
```
### 在网络摄像头上运行
注释掉 `VIDEO_PATH` 并切换至摄像头输入:
```
# VIDEO_PATH = r"C:\path\to\video.mp4"
cap = cv2.VideoCapture(0) # 0 = default webcam, 1 = external
```
### 在 IP 摄像头 / RTSP 流上运行
```
cap = cv2.VideoCapture("rtsp://username:password@192.168.1.x:554/stream")
# 或者使用 DroidCam(手机作为 webcam):
cap = cv2.VideoCapture("http://192.168.1.x:4747/video")
```
**随时按 `Q` 键停止。**
### 输出
| 文件 | 内容 |
|---|---|
| `output_annotated.mp4` | 完整的带标注视频会话记录 |
| `alert_clips/alert_N.mp4` | 自动保存的事件片段(前 2 秒 + 后 3 秒) |
| `detection_log.txt` | 包含时间戳和规则数值的警报日志 |
## 评估
要在带标注的视频集上测量系统准确率:
### 1. 在 `evaluate.py` 中配置视频列表
```
TEST_DIR = r"C:\path\to\test_videos"
VIOLENCE_CLIPS = ["V_1.mp4", "V_2.mp4", ...]
NONVIOLENCE_CLIPS = ["NV_1.mp4", "NV_2.mp4", ...]
```
### 2. 运行评估
```
python evaluate.py
```
结果将打印到终端并保存至 `evaluation_results.txt`。
## 配置
所有阈值均集中在 `config.py` 中:
```
VELOCITY_THRESHOLD = 15 # px/frame — minimum speed to flag Rule 1
OVERLAP_THRESHOLD = 0.20 # IoU — minimum bounding box overlap for Rule 2
CONFIDENCE_THRESHOLD = 0.5 # YOLO detection confidence minimum
SMOOTHING_WINDOW = 3 # consecutive frames before alert fires (main.py)
BUFFER_SECONDS = 2 # seconds of pre-alert footage to buffer
POST_ALERT_SECS = 3 # seconds of post-alert footage to save
```
### 调优指南
| 症状 | 解决方案 |
|---|---|
| 误报过多 | 提高 `VELOCITY_THRESHOLD` 或 `OVERLAP_THRESHOLD` |
| 漏报真实斗殴 | 降低 `VELOCITY_THRESHOLD` 或 `OVERLAP_THRESHOLD` |
| 警报触发太慢 | 减小 `SMOOTHING_WINDOW`(最小值为 2) |
| 出现单帧误报 | 提高 `SMOOTHING_WINDOW` |
## 检测日志格式
每次警报都会生成如下的日志条目:
```
17:33:56 ALERT | t=12.73s frame=382 | Person #5 | rules=['velocity', 'overlap'] | vel=20.1px iou=0.30 pose=False | consecutive=3 frames
```
| 字段 | 描述 |
|---|---|
| `t=12.73s` | 视频中的时间点 |
| `frame=382` | 视频帧号 |
| `Person #5` | DeepSORT 跟踪 ID |
| `rules=[...]` | 哪些规则被触发 |
| `vel=20.1px` | 滚动平均速度 |
| `iou=0.30` | 与任意其他人的最大 IoU |
| `pose=False` | 是否检测到手臂抬起 |
| `consecutive=3` | 触发警报前条件已成立的帧数 |
## 已知的局限性
- **俯视摄像头** —— 姿态估计(规则 3)在自上而下的角度下会失效。边界框的形状和重叠模式会发生显著变化。
- **缓慢的缠斗** —— 持续的低运动暴力行为(如锁喉、抱摔)可能无法突破速度阈值。
- **基于像素的速度** —— 未根据摄像机距离进行归一化。距离摄像机较远的人员在相同的物理运动下产生的像素位移较小。
- **单摄像头范围** —— 不具备多摄像头跟踪或跨视频流的联动协调能力。
- **阈值泛化** —— 数值是在测试数据集上校准的。不同的环境(不同的光照、人群密度、摄像机角度)可能需要重新校准。
- **MediaPipe 依赖 CPU** —— 无论 GPU 是否可用,姿态估计都在 CPU 上运行。这是主要的吞吐量瓶颈。
- **无面部识别或身份鉴别** —— 跟踪 ID 仅仅是本次运行期间有效的整数标识。
## 技术栈
| 组件 | 库 | 作用 |
|---|---|---|
| 人员检测 | YOLOv8 Nano (Ultralytics) | 定位每一帧中的所有人员 |
| 多目标跟踪 | DeepSORT (deep-sort-realtime) | 分配持久 ID |
| 姿态估计 | MediaPipe PoseLandmarker 0.10.32 | 身体关节检测 |
| 视频 I/O | OpenCV | 读取帧、画面标注、结果输出 |
| GPU 推理 | PyTorch 2.6.0 + CUDA 12.4 | YOLO 加速 |
| 数值运算 | NumPy | 数组数学计算 |
| 可视化 | Matplotlib | 评估图表绘制 |
## 数据集
**Real-Life Violence Situations Dataset**
- 来源:[Kaggle — Mohamed Mustafa](https://www.kaggle.com/datasets/mohamedmustafa/real-life-violence-situations-dataset)
- 2,000 个短视频片段(每个 5–10 秒):1,000 个暴力 / 1,000 个非暴力
- 真实现场录像 —— 非摆拍或合成画面
- 仅用于评估 —— 未进行任何模型训练
## 未来改进
- 使用 **YOLOv8-pose** 替代 MediaPipe,实现 GPU 加速的关节检测
- 增加 **基于边界框高度的速度归一化**,以修正摄像机距离带来的偏差
- 将 **徘徊检测** 作为第四条行为规则纳入系统
- 构建一个 **Web 仪表板**(Flask/Streamlit),用于实时监控源查看和警报复核
- 通过共享事件日志添加 **多摄像头联动**
- 实现 **操作员反馈闭环** —— 被忽略的误报可用于指导阈值的校准
- 增加 **音频整合**,以提供额外的行为信号
## 参考文献
- Ultralytics YOLOv8 — https://github.com/ultralytics/ultralytics
- MediaPipe Pose Landmarker — https://developers.google.com/mediapipe/solutions/vision/pose_landmarker
- DeepSORT — https://github.com/levan92/deep_sort_realtime
- Bewley et al. (2016) — Simple Online and Realtime Tracking (SORT). ICIP 2016.
- Wojke et al. (2017) — Deep SORT with Deep Association Metric. ICIP 2017.
- Jocher et al. (2023) — Ultralytics YOLOv8. doi:10.5281/zenodo.7347926
*作为 2025–2026 学年第六学期项目 1 的一部分构建*
标签:DeepSORT, Vectored Exception Handling, YOLOv8, 人工智能, 凭据扫描, 用户模式Hook绕过, 目标跟踪, 行为识别, 视频监控, 计算机视觉, 逆向工具