# Fight-Detection **Repository Path**: pojcode/fight-detection ## Basic Information - **Project Name**: Fight-Detection - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-29 - **Last Updated**: 2026-03-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Fight Detection System 基于 **YOLOv8n + MediaPipe Pose** 的 PC 端多路视频打架行为检测系统。 ## 功能特性 - **多路视频输入**:支持同时处理多个本地视频文件,多线程并行处理 - **双后端检测**:支持 YOLOv8n(ultralytics)和 ONNX Runtime 两种推理后端 - **人员检测**:YOLOv8n 轻量化模型,仅检测 person 类别 - **人体关键点**:MediaPipe Pose 提取 33 个关键点,绘制差异化火柴人骨架 - **打架行为分析**:基于多人姿态特征综合判断(近身距离、手臂指向、运动幅度等) - **多目标跟踪**:支持基于 IoU 的多目标跟踪(可选) - **告警渲染**:检测到打架时红色边框 + 顶部告警横幅 - **隐私保护**:全帧高斯模糊 + 随机像素扰动(毛玻璃遮罩,可关闭) - **灵活配置**:支持命令行参数和配置文件双重控制 ## 项目结构 ``` Fight-Detection/ ├── main.py # 程序入口 ├── config.py # 全局配置参数 ├── pipeline.py # 单路视频处理管道 ├── scheduler.py # 多路视频线程调度器 ├── requirements.txt # Python 依赖 ├── README.md # 项目文档 ├── yolov8n.pt # YOLOv8n 模型文件 ├── yolov8n.onnx # ONNX 格式模型文件 ├── video/ # 测试视频目录(可选) ├── models/ │ ├── __init__.py │ ├── base.py # ObjectDetector + PoseExtractor 抽象基类 │ ├── yolo_detector.py # YOLOv8n 人员检测器(ultralytics 后端) │ ├── onnx_detector.py # YOLOv8n 人员检测器(ONNX 后端) │ └── mediapipe_pose.py # MediaPipe Pose 关键点提取器 ├── analyzers/ │ ├── __init__.py │ └── fight_analyzer.py # 打架行为多特征融合分析器 ├── visualization/ │ ├── __init__.py │ ├── skeleton_drawer.py # 火柴人骨架绘制 │ └── alert_renderer.py # 告警渲染(红框+横幅+隐私遮罩) └── trackers/ ├── __init__.py └── iou_tracker.py # IoU 多目标跟踪器 ``` ## 快速开始 ### 安装依赖 ```bash cd examples/Fight-Detection pip install -r requirements.txt ``` ### 运行 ```bash # 单路视频(默认使用 YOLO 后端) python main.py your_video.mp4 # 多路视频 python main.py video1.mp4 video2.mp4 video3.mp4 # 使用 ONNX 后端(更快,适合 CPU) python main.py --detector-backend onnx --detector-model yolov8n.onnx your_video.mp4 # 调整检测置信度 python main.py --detector-conf 0.3 your_video.mp4 # 调整打架判定阈值 python main.py --fight-threshold 0.5 your_video.mp4 # 跳帧加速(每 3 帧处理 1 帧) python main.py --skip-frames 2 your_video.mp4 # 禁用隐私遮罩 python main.py --no-privacy-mask your_video.mp4 # 详细日志 python main.py --verbose your_video.mp4 ``` ### 退出 在任意视频窗口按 `q` 键退出。 ## 命令行参数 | 参数 | 默认值 | 说明 | |------|--------|------| | `videos` | - | 视频文件路径(必填,支持多个) | | `--detector-backend` | `yolo` | 检测后端:`yolo`(ultralytics)或 `onnx` | | `--detector-model` | `yolov8n.pt` | 检测模型路径(根据后端自动匹配) | | `--detector-conf` | `0.45` | 检测置信度阈值 | | `--fight-threshold` | `0.65` | 打架评分阈值 | | `--max-workers` | `4` | 最大并行线程数 | | `--skip-frames` | `0` | 跳帧数(0=不跳帧) | | `--no-privacy-mask` | - | 禁用隐私遮罩 | | `--verbose` / `-v` | - | 启用详细日志 | ## 架构设计 ```mermaid graph TD A[main.py 入口] --> B[FightDetectionScheduler] B --> C1[VideoPipeline 线程1] B --> C2[VideoPipeline 线程2] B --> C3[VideoPipeline 线程N] C1 --> D[ObjectDetector - YOLOv8n/ONNX] C1 --> E[PoseExtractor - MediaPipe] C1 --> F[IoU Tracker 可选] C1 --> G[FightAnalyzer] C1 --> H[AlertRenderer + SkeletonDrawer] C1 --> I[PrivacyMasker] D -.-> J[ObjectDetector ABC] E -.-> K[PoseExtractor ABC] ``` ### 打架检测算法 采用多特征融合评分: 1. **近身距离 × 运动速度**(权重 0.40):基于两人躯干中心的归一化距离 × 运动速度,近身且运动快评分高 2. **手臂指向对方**(权重 0.30):计算手腕连线是否指向对方躯干,形成攻击姿态评分更高 3. **手臂伸展 + 抬起**(权重 0.30):分析肘-腕关节角度和手腕位置,手臂伸展且抬起(挥拳姿态)评分更高 评分经时间窗口滑动平均平滑后,连续 N 帧超过阈值才报警,避免误报。 ### 硬件适配 `ObjectDetector` 和 `PoseExtractor` 均为抽象基类,可替换为 RKNN / TensorRT 等实现: ```python from models.base import ObjectDetector class RKNNDetector(ObjectDetector): def detect(self, frame): # RKNN 硬件推理 ... def load_model(self): # 加载 .rknn 模型 ... ``` 当前已支持双后端: - **YOLO 后端**:使用 ultralytics 包,推理速度较慢但兼容性好 - **ONNX 后端**:使用 onnxruntime,CPU 推理速度更快 ## 技术栈 - **Python** 3.8+ - **ultralytics** >= 8.0.0(YOLOv8n 人员检测) - **onnxruntime** >= 1.16.0(ONNX 推理加速) - **mediapipe** == 0.10.14(33 关键点提取) - **opencv-python** >= 4.6.0(视频处理 + 可视化) - **concurrent.futures**(多线程调度) ## 配置说明 所有配置参数集中在 `config.py` 中,通过 `AppConfig` 数据类统一管理。配置参数可以通过两种方式修改: ### 方式一:命令行参数 ```bash python main.py --detector-conf 0.3 --fight-threshold 0.5 video.mp4 ``` ### 方式二:直接修改 config.py ```python from config import AppConfig config = AppConfig() # 修改检测器配置 config.detector.confidence_threshold = 0.3 config.detector.backend = "onnx" # 修改打架分析配置 config.fight.fight_score_threshold = 0.5 config.fight.min_fight_frames = 10 # 修改可视化配置 config.visualization.privacy_blur_kernel = 0 # 关闭隐私遮罩 ``` ### 检测器配置 (DetectorConfig) | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `model_path` | str | `yolov8n.pt` | 模型文件路径 | | `backend` | str | `yolo` | 推理后端:`yolo`(ultralytics)或 `onnx` | | `onnx_device` | str | `cpu` | ONNX 推理设备:`cpu` 或 `cuda` | | `confidence_threshold` | float | `0.45` | 检测置信度阈值(0-1) | | `iou_threshold` | float | `0.45` | NMS IoU 阈值(0-1) | | `classes` | list | `[0]` | 检测类别(默认仅检测 person) | | `imgsz` | int | `640` | 输入图像尺寸 | **使用示例**: ```python config.detector.confidence_threshold = 0.3 # 降低置信度阈值,检测更多人 config.detector.backend = "onnx" # 切换到 ONNX 后端加速 config.detector.onnx_device = "cuda" # 使用 GPU 加速(需安装 CUDA 版本) ``` ### 打架分析配置 (FightConfig) **距离特征**: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `distance_threshold` | float | `0.8` | 归一化距离阈值(bbox高度倍数) | **手臂姿态特征**: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `arm_angle_threshold` | float | `45.0` | 肘-腕角度阈值(度),低于此值视为伸展 | **运动幅度特征**: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `motion_threshold` | float | `0.05` | 归一化运动阈值(保留兼容性) | | `arm_motion_threshold` | float | `0.03` | 手臂快速运动阈值(归一化) | | `motion_asymmetry_threshold` | float | `0.3` | 双方运动幅度差距阈值,超过则抑制评分 | **评分融合权重**: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `proximity_motion_weight` | float | `0.40` | 近身距离 × 运动速度(联合特征) | | `arm_targeting_weight` | float | `0.30` | 手腕指向对方 | | `arm_pose_weight` | float | `0.30` | 手臂伸展 + 抬起 | **综合判断**: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `fight_score_threshold` | float | `0.65` | 打架评分阈值(0-1) | | `min_persons_for_fight` | int | `2` | 最少参与人数 | **持续时间和冷却期**: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `min_fight_frames` | int | `8` | 连续 N 帧超过阈值才报警 | | `cooldown_frames` | int | `15` | 报警后 N 帧内不再重复报警 | **时间窗口平滑**: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `smoothing_window` | int | `5` | 滑动平均窗口帧数 | **使用示例**: ```python # 提高检测敏感度 config.fight.fight_score_threshold = 0.5 # 降低打架阈值 config.fight.min_fight_frames = 5 # 减少连续帧数 # 降低误报 config.fight.fight_score_threshold = 0.7 # 提高打架阈值 config.fight.min_fight_frames = 15 # 增加连续帧数 config.fight.cooldown_frames = 30 # 延长冷却期 # 调整特征权重 config.fight.proximity_motion_weight = 0.5 # 增加距离×运动权重 config.fight.arm_targeting_weight = 0.25 # 降低手臂指向权重 # 调整时间平滑 config.fight.smoothing_window = 10 # 增加平滑窗口 ``` ### 可视化配置 (VisualizationConfig) **火柴人骨架**: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `skeleton_color` | tuple | `(0, 255, 128)` | 骨架颜色(BGR 格式) | | `skeleton_thickness` | int | `2` | 骨架线条粗细 | | `keypoint_radius` | int | `3` | 关键点半径 | **差异化绘制**: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `visibility_threshold` | float | `0.2` | 关键点可见度阈值 | | `arm_skeleton_thickness` | int | `3` | 手臂骨架粗细 | | `torso_skeleton_thickness` | int | `2` | 躯干骨架粗细 | | `leg_skeleton_thickness` | int | `1` | 腿部骨架粗细 | | `wrist_keypoint_radius` | int | `4` | 手腕关键点半径 | **告警渲染**: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `alert_border_color` | tuple | `(0, 0, 255)` | 告警边框颜色(BGR) | | `alert_border_thickness` | int | `3` | 告警边框粗细 | | `alert_banner_height` | int | `40` | 告警横幅高度 | | `alert_banner_alpha` | float | `0.7` | 告警横幅透明度(0-1) | | `alert_text` | str | `"FIGHT DETECTED!"` | 告警文字内容 | | `alert_font_scale` | float | `1.0` | 告警文字大小 | | `alert_font_color` | tuple | `(0, 0, 255)` | 告警文字颜色(BGR) | **隐私遮罩**: | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `privacy_blur_kernel` | int | `31` | 高斯模糊核(奇数,0=关闭) | | `privacy_noise_intensity` | int | `15` | 像素扰动强度(0=关闭) | **使用示例**: ```python # 自定义颜色 config.visualization.skeleton_color = (0, 255, 255) # 黄色骨架 config.visualization.alert_border_color = (255, 0, 0) # 蓝色告警 # 调整可视化细节 config.visualization.arm_skeleton_thickness = 4 config.visualization.wrist_keypoint_radius = 6 # 关闭隐私遮罩 config.visualization.privacy_blur_kernel = 0 config.visualization.privacy_noise_intensity = 0 # 自定义告警文字 config.visualization.alert_text = "警告:检测到打架!" config.visualization.alert_font_color = (0, 0, 255) ``` ### 管道配置 (PipelineConfig) | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `display_width` | int | `1280` | 显示窗口宽度 | | `display_height` | int | `720` | 显示窗口高度 | | `skip_frames` | int | `0` | 跳帧数(0=不跳帧) | | `show_fps` | bool | `True` | 是否显示 FPS | **使用示例**: ```python # 降低分辨率提升性能 config.pipeline.display_width = 640 config.pipeline.display_height = 480 # 跳帧加速 config.pipeline.skip_frames = 2 # 每 3 帧处理 1 帧 ``` ### 调度器配置 (SchedulerConfig) | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `max_workers` | int | `4` | 线程池最大线程数 | **使用示例**: ```python # 根据核心数调整 config.scheduler.max_workers = 8 # 使用 8 个线程 ``` ### 跟踪器配置 (TrackerConfig) | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `enabled` | bool | `False` | 是否启用跟踪 | | `iou_threshold` | float | `0.3` | IoU 匹配阈值 | | `max_lost_frames` | int | `30` | 最大容忍丢失帧数 | **使用示例**: ```python # 启用跟踪 config.tracker.enabled = True config.tracker.iou_threshold = 0.5 # 提高匹配严格度 config.tracker.max_lost_frames = 60 # 延长丢失容忍时间 ``` ## 性能优化建议 1. **使用 ONNX 后端**:CPU 环境下使用 `--detector-backend onnx` 可提升 2-3 倍推理速度 2. **跳帧处理**:使用 `--skip-frames` 参数跳过部分帧,在保持检测精度的同时提升帧率 3. **调整分辨率**:修改 `PipelineConfig.display_width/height` 降低显示分辨率 4. **降低检测频率**:通过 `skip_frames` 参数每 N+1 帧处理一帧 5. **限制并行线程数**:根据 CPU 核心数调整 `--max-workers` ## 许可证 本项目基于 Ultralytics YOLOv8 许可证,请参考主项目许可证。