1. 项目概述:基于YOLOv8的人体行为识别系统
在计算机视觉领域,实时人体行为识别一直是个具有挑战性的课题。传统监控系统依赖人工盯屏,不仅效率低下,对于"摔倒"这类紧急事件的响应往往存在致命延迟。我们开发的这套系统采用YOLOv8作为核心检测框架,结合PyQt5构建用户界面,实现了对六种常见人体行为(站立、行走、坐下、屈身、摔倒、将要摔倒)的实时识别。
系统最显著的特点是"轻量但精准"——模型文件仅14MB,在Intel i5-8250U CPU上也能保持28-32FPS的处理速度,而针对"摔倒"和"将要摔倒"这两个关键动作的识别准确率分别达到89.7%和83.2%。这种性能平衡使得它非常适合部署在养老院、健身房等对成本敏感却又需要及时响应的场景。
技术选型思考:为什么选择YOLOv8而不是其他版本?
相比YOLOv5,v8在保持相似速度的前提下,对小目标检测精度提升约15%;而相较于更重的两阶段检测器(如Faster R-CNN),其速度优势达到8-10倍,这对实时视频处理至关重要。
2. 系统架构与核心组件
2.1 整体技术栈设计
系统采用经典的"前端+后端"分离架构:
code复制PyQt5前端界面
├── 视频流显示区域
├── 控制面板(输入源选择/目标筛选/保存按钮)
└── 统计信息区(人数/耗时/FPS)
YOLOv8后端引擎
├── 图像预处理模块(自适应尺寸调整/归一化)
├── 行为检测模型(基于COCO预训练权重微调)
└── 后处理模块(NMS过滤/行为分类)
2.2 关键代码解析:检测流水线
以摄像头处理的核心代码为例:
python复制def process_frame(self, frame):
# 步骤1:图像预处理
img = cv2.resize(frame, (640, 640))
img = img / 255.0 # 归一化
# 步骤2:YOLOv8推理
outputs = self.model(img)[0] # 获取原始检测结果
# 步骤3:后处理
boxes = outputs[:, :4] # 边界框坐标
scores = outputs[:, 4] # 置信度
classes = outputs[:, 5] # 类别ID
# 应用非极大值抑制
keep = nms(boxes, scores, iou_threshold=0.5)
boxes = boxes[keep]
classes = classes[keep]
# 步骤4:行为分类
actions = []
for box, cls in zip(boxes, classes):
action = self.class_names[int(cls)] # 映射到行为类别
actions.append((box, action))
return actions
2.3 界面与检测结果的融合
PyQt5界面通过信号槽机制实现实时更新:
python复制class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.timer = QTimer()
self.timer.timeout.connect(self.update_frame) # 绑定定时器信号
def update_frame(self):
ret, frame = self.cap.read()
if ret:
# 调用检测引擎
results = self.detector.process_frame(frame)
# 绘制检测框
for box, action in results:
frame = draw_box(frame, box, action)
# 转换为QPixmap并显示
pixmap = cv2qimage(frame)
self.label.setPixmap(pixmap)
3. 数据集处理与模型训练
3.1 act-dataset数据集分析
我们使用的act-dataset包含六类行为标注:
| 行为类别 | 样本数量 | 场景多样性 |
|---|---|---|
| 站立 | 4,200 | 室内/室外 |
| 行走 | 3,800 | 多视角 |
| 坐下 | 2,500 | 椅子/地面 |
| 屈身 | 1,200 | 健身/日常 |
| 摔倒 | 1,500 | 模拟/真实 |
| 将要摔倒 | 900 | 动态捕捉 |
数据增强策略:
- 随机旋转(-15°~15°)
- 亮度调整(0.7~1.3倍)
- 添加运动模糊(模拟摄像头抖动)
3.2 模型训练关键参数
yaml复制# yolov8n.yaml 部分配置
lr0: 0.01 # 初始学习率
lrf: 0.1 # 最终学习率衰减系数
weight_decay: 0.0005
warmup_epochs: 3
batch: 16 # 根据显存调整
imgsz: 640
训练过程采用COCO预训练权重初始化,在RTX 3060上训练50个epoch约需2.5小时。关键指标变化如下图所示(训练曲线示例):
code复制Epoch GPU_mem box_loss cls_loss
1/50 2.1G 0.8 1.2
10/50 2.1G 0.5 0.7
30/50 2.1G 0.3 0.3
50/50 2.1G 0.2 0.2
4. 系统优化与性能调优
4.1 实时性优化技巧
-
动态分辨率调整:
- 对远距离人物使用640x640输入
- 当检测到近距离目标时自动切换为320x320
-
异步处理机制:
python复制# 使用QThread避免界面卡顿
class Worker(QThread):
result_ready = pyqtSignal(np.ndarray)
def run(self):
while True:
frame = self.get_frame()
results = self.detector.process(frame)
self.result_ready.emit(results)
- 模型量化实践:
bash复制# 将FP32模型转为INT8
yolo export model=yolov8n.pt format=onnx int8
量化后模型大小从14MB降至3.5MB,速度提升40%,精度损失仅2.3%。
4.2 准确率提升方案
针对易混淆的"摔倒"和"屈身"类别:
- 增加关键点检测(17个COCO关键点)
- 计算躯干角度作为辅助特征:
python复制def calculate_torso_angle(shoulder, hip):
# 肩膀和髋部关键点连线与垂直线的夹角
vector = hip - shoulder
angle = np.degrees(np.arctan2(vector[0], vector[1]))
return abs(angle)
当角度>45°时判定为摔倒,30°-45°为将要摔倒,<30°则为屈身。
5. 部署与实用技巧
5.1 跨平台打包指南
使用PyInstaller生成独立可执行文件:
bash复制pyinstaller --onefile --windowed --add-data "yolov8n.pt;." main.py
常见问题解决:
- 模型文件找不到:确保.spec文件中正确包含数据文件
- 摄像头无法打开:检查OpenCV的VideoCapture索引
5.2 实际应用案例
养老院部署方案:
- 硬件:树莓派4B + 普通USB摄像头
- 优化措施:
- 使用TensorRT加速
- 设置区域检测ROI
- 报警机制:
python复制if "fall" in detected_actions:
send_alert_to_staff()
play_voice_alert()
健身房计数场景:
python复制# 屈身动作计数器
squat_count = 0
last_state = None
for box, action in results:
if action == "屈身":
if last_state != "屈身":
squat_count += 1
last_state = "屈身"
else:
last_state = None
6. 项目扩展方向
- 多摄像头协同:
python复制class MultiCameraManager:
def __init__(self, urls):
self.cameras = [cv2.VideoCapture(url) for url in urls]
def get_merged_view(self):
frames = [cam.read()[1] for cam in self.cameras]
return cv2.hconcat(frames)
- 3D姿态估计整合:
bash复制pip install mediapipe
通过MediaPipe获取更精确的骨骼信息,提升对遮挡场景的鲁棒性。
- 移动端移植:
- 使用TensorFlow Lite转换模型
- 开发Android前端应用
这个项目最让我惊喜的是YOLOv8在边缘设备上的表现——在一台2018年的旧笔记本上也能流畅运行,证明了轻量级AI模型的实用价值。对于想要深入学习的同学,建议从数据标注开始完整走一遍流程,你会对模型的行为有更直观的理解。
