尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

YOLOv5+Python三合一:人脸识别表情识别异常行为检测系统解析

发布时间:2026/9/24 22:35:41

资讯中心
01
ARTICLE

YOLOv5+Python三合一:人脸识别表情识别异常行为检测系统解析

YOLOv5+Python三合一:人脸识别表情识别异常行为检测系统解析
简介基于Yolov5Python实现的人脸识别、细粒度表情识别与异常行为检测源码面向准备毕业设计、期末大作业或课程设计的高校学生也适合希望快速上手YOLOv5视觉应用、开展人脸与行为分析的开发者。压缩包内共107个文件以37个py源码文件、18个yaml模型配置、21个txt文本说明为核心辅以10张jpg示例图、4张png图片以及pt权重、ui界面、xml、mat和Dockerfile等文件整体大小24.81MB目录结构清晰便于按功能模块查阅和二次修改。目前已有269人学习下载属于导师认可的高分项目各模块代码附有详细注释与关键说明新手也能理解核心逻辑。系统涵盖人脸识别、细粒度表情识别和异常行为检测三大模块功能完善、界面美观、操作简单配置好依赖后即可直接运行既能作为完整项目提交也适合二次开发与算法学习并配有基础UI便于交互操作。1. 基于Yolov5Python的人脸识别项目三合一系统到底怎么落地如果你正在找毕业设计或者课程设计的源码大概率看过不少号称“人脸识别表情识别异常行为检测”的项目但真正下载下来能跑通的没几个。这套基于Yolov5Python实现的源码是我拆过的同类项目里比较省心的一套——三个核心功能打包在一个系统里人脸识别负责“是谁”细粒度表情识别负责“什么情绪”异常行为检测负责“在干什么”互相独立又能联动。代码里注释写得比较全新手照着部署能跑起来老手也能直接改检测头或者换backbone做二次开发。我先把整体结论放这儿这项目不是那种PPT级别的demo检测精度和界面完成度都够得上答辩演示但前提是你得把环境配对、权重文件放对位置否则翻车概率不小。下面我从选型逻辑到部署细节一步步拆给你看。2. 为什么是Yolov5而不是其他检测框架选型逻辑与系统架构2.1 Yolov5在轻量级视觉任务里的真实定位先说一个很多人纠结的问题人脸识别、表情识别、行为检测这三个任务各有一堆专用算法为什么偏偏用Yolov5统一做我的看法是对于需要同时跑三个任务的单机系统Yolov5的性价比最高。人脸检测用MTCNN或者RetinaFace确实精度高但你要在同一个进程里再跑表情分类和行为识别显存和CPU占用会打架。Yolov5的检测头是解耦的一个模型权重里可以同时输出多个类别的bbox你只需要准备好不同任务的标注数据训练成多类别检测即可。这套源码的做法是人脸识别和表情识别复用同一个检测模型检测到人脸框之后再通过分类分支输出身份ID和表情类别行为检测单独用一个模型检测目标是摔倒、挥手、奔跑这些异常动作。两个模型可以串行推理也可以分两个线程并行处理源码里默认是串行方便新手理解流程。2.2 整体架构与数据流整个系统分成三层。底层是OpenCV负责视频流读取和帧预处理中间层是Yolov5的推理模块负责输出检测框、置信度和类别顶层是业务逻辑层把检测结果映射成“某某人在什么时间做出了什么表情触发了什么异常预警”。这里有一个关键设计异常行为检测的判定不是单纯看单帧的检测结果而是结合了时序信息——连续N帧检测到同一行为才触发报警避免单帧误检。视频流输入 → 帧解码 → Yolov5推理 → 后处理(NMS) → 业务判定 → 结果可视化/报警后处理部分用的是Yolov5自带的NMS置信度阈值默认设0.5IOU阈值设0.45这两个参数在异常行为检测里建议调低到0.4和0.4因为行为检测的bbox通常比较大目标重叠率低适当放宽阈值能减少漏检。3. 环境部署与依赖安装从零到能跑通推理3.1 Python环境与依赖版本对照这是整个项目最容易翻车的一步我直接给你一组能跑通的版本组合。Python建议3.8或者3.9不要用3.10以上因为有些老版本torch的算子不兼容。PyTorch用1.10到1.12之间都行CUDA用11.3配套的版本。如果你机器没有NVIDIA显卡CPU也能跑推理只是速度会慢很多——Yolov5s模型CPU推理一帧大概200-400毫秒做演示够用做实时视频流就会明显卡顿。# 创建虚拟环境避免污染系统Python conda create -n yoloface python3.8 -y conda activate yoloface # 安装PyTorch以CUDA 11.3为例 pip install torch1.11.0cu113 torchvision0.12.0cu113 --extra-index-url https://download.pytorch.org/whl/cu113 # 安装项目依赖 pip install -r requirements.txtrequirements.txt里主要包含opencv-python、numpy、pandas、matplotlib、seaborn、tqdm、pyyaml这些常规库。注意一点不要直接pip install opencv-python-headless这个版本不带GUI模块项目里的可视化窗口会起不来。装的时候用conda install opencv会更省心会自动帮你解决ffmpeg的依赖。3.2 目录结构与权重文件放置源码下载解压之后目录结构大概是这样的detect.py是推理入口train.py是训练脚本models文件夹放的是Yolov5的模型定义文件weights文件夹放预训练权重。第一次运行之前你需要在weights文件夹里放入对应的.pt文件——人脸检测模型一个行为检测模型一个。如果下载的压缩包里没带权重因为文件太大经常被网盘砍掉你就需要自己训练或者从官方Yolov5模型转换。# 目录结构参考 project/ ├── detect.py ├── train.py ├── models/ │ ├── yolo5s.yaml │ └── common.py ├── weights/ │ ├── face_detect.pt │ └── action_detect.pt ├── utils/ ├── data/ └── runs/权重缺失是下载类项目最常见的坑如果运行报错提示找不到.pt文件先去确认weights目录有没有东西。如果确实缺权重有两个补救方案一是用Yolov5官方提供的yolov5s.pt做迁移学习用自己的数据集微调二是直接用开源的人脸检测权重比如WIDER Face数据集上训练的模型顶替。我个人建议先跑通推理流程再谈训练不然排查问题的时候你分不清是代码问题还是权重问题。3.3 首次运行与常见启动报错代码跑通第一个里程碑是能弹出视频窗口看到检测框。运行命令很简单python detect.py --source 0 --weights weights/face_detect.pt --conf-thres 0.5--source 0代表读取摄像头也可以传视频文件路径。如果你看到窗口弹出来但检测框没画上先查cv2.imshow的显示逻辑——有些版本的OpenCV在高DPI屏幕上会把窗口放大导致看不见框这个可以在代码里把窗口分辨率固定住解决。如果直接报错ModuleNotFoundError大概率是依赖没装全把requirements.txt逐行检查一遍。4. 三大核心任务的代码实现识别、表情与行为检测4.1 人脸识别模块检测框到身份映射的实现人脸识别这块源码用的是“检测特征比对”的两段式思路。Yolov5只负责把人脸框出来然后裁剪出人脸区域送入特征提取网络得到128维特征向量再和底库里的特征做余弦相似度比对。底库用pickle文件存储格式是字典key是人名value是特征向量列表。为什么不用分类头直接输出人名因为人脸识别是开放集问题——你不可能预先定义所有可能的人而特征比对天然支持新增人脸的场景。# 人脸特征提取与比对的核心逻辑 import cv2 import numpy as np import pickle from models.experimental import attempt_load from utils.general import non_max_suppression def extract_face_feature(face_img, feature_model): 提取人脸区域的特征向量 # 预处理缩放、归一化 face_img cv2.resize(face_img, (112, 112)) face_img face_img.astype(np.float32) / 255.0 face_img (face_img - 0.5) / 0.5 # 转成模型输入格式NCHW input_tensor np.transpose(face_img, (2, 0, 1))[np.newaxis, ...] input_tensor torch.from_numpy(input_tensor).float() with torch.no_grad(): feature feature_model(input_tensor) # L2归一化便于后续余弦相似度计算 feature feature / np.linalg.norm(feature) return feature.flatten()这段代码里有两个参数需要注意resize到112x112是人脸特征网络的固定输入尺寸改成别的尺寸会导致特征质量下降归一化用0.5均值0.5方差的方式这个是和训练时保持一致的不能改成ImageNet那套[0.485, 0.456, 0.406]的均值方差。余弦相似度阈值源码里设的是0.6低于这个值判定为陌生人实际使用的话建议在0.55到0.65之间调阈值调低漏检少但误识别多调高则反过来。4.2 细粒度表情识别多标签分类的工程处理细粒度表情识别是这套源码里我觉得做得比较用心的地方。它不是简单分成高兴、难过那种七大类而是引入了多个维度的描述——比如“开心-大笑”“开心-微笑”“惊讶-微张嘴巴”这种细粒度标签的好处是能捕捉更多交互细节但在工程实现上有个麻烦一个表情可能同时属于多个维度不能简单用softmax做单标签分类。源码的处理方式是把输出层改成多个二分类头每个头对应一个表情属性维度损失函数用BCEWithLogitsLoss而不是CrossEntropyLoss。这样训练的时候一张“开心大笑”的图在“是否开心”和“是否大笑”两个头上都标1在“是否生气”的头上标0。推理的时候每个头独立sigmoid输出概率超过0.5就认为是该属性命中。# 多标签表情分类的推理逻辑 import torch import torch.nn.functional as F def predict_expression(face_crops, model): 输入: 多张人脸裁剪图 输出: 每张人脸的细粒度表情标签 labels_map { 0: 开心, 1: 微笑, 2: 正常, 3: 惊讶, 4: 难过, 5: 愤怒 } results [] with torch.no_grad(): logits model(face_crops) # sigmoid将logits转为概率 probs torch.sigmoid(logits) # 阈值0.5判定该属性是否命中 preds (probs 0.5).int() for i in range(preds.shape[0]): hit_indices torch.nonzero(preds[i]).squeeze(1).tolist() face_labels [labels_map[idx] for idx in hit_indices] results.append({ labels: face_labels, probs: probs[i][preds[i] 1].tolist() }) return results细粒度表情识别这里有一个经验阈值0.5是起步值实际用的时候建议把“正常”类的阈值提高到0.6把其他表情的阈值保持在0.5。原因是训练数据里“正常”表情占了绝大多数模型对这类样本的置信度天然偏高不提高阈值会出现所有表情都被预测成“正常”的情况。4.3 异常行为检测时序判定与报警触发机制异常行为检测是整个系统里唯一涉及时序逻辑的模块。单纯的Yolov5检测是逐帧的但“摔倒”这个行为单帧看可能只是一个人躺在地上需要结合前后帧的姿态变化才能判断是不是摔倒。源码的实现思路并不复杂维护一个长度为10的滑动窗口窗口内同一目标的行为类别变化满足特定模式才触发报警。# 基于滑动窗口的行为判定 from collections import deque class BehaviorDetector: def __init__(self, window_size10, alert_threshold5): self.window deque(maxlenwindow_size) self.alert_threshold alert_threshold def update_and_check(self, behavior_id, confidence): 每帧调用一次传入当前帧检测到的行为ID 返回: 是否触发报警 self.window.append({ behavior_id: behavior_id, confidence: confidence }) # 统计窗口内同一种异常行为出现的次数 if len(self.window) self.window.maxlen: return False abnormal_count sum(1 for item in self.window if item[behavior_id] behavior_id and item[confidence] 0.5) # 连续超过一半帧数检测到异常行为则报警 if abnormal_count self.alert_threshold: self.window.clear() # 报警后清空窗口防止连续重复报警 return True return False这个时序判定有几个参数决定了系统的灵敏度和误报率。window_size是滑动窗口长度越长越稳定但响应越慢10帧在30fps的视频流里是0.33秒的观察窗口比较合理。alert_threshold是报警阈值默认5代表窗口内一半以上的帧都检测到异常才报警。如果实际场景里误报频繁可以把阈值调高到7或者8代价是报警有延迟。还有一个细节值得注意self.window.clear()这个操作。报警之后清空窗口是为了防止同一个行为连续触发多次报警但这也意味着如果异常行为一直持续系统每10帧会报警一次。如果需求是“持续异常只要报一次”你需要额外维护一个报警状态标志位源码里没有做这个去重你可以自己加上。5. 避坑指南训练与部署中的五个高频翻车点5.1 现象推理速度极慢CPU占用100%但帧率不到5fps原因没有启用CUDA加速PyTorch默认在CPU上跑推理。检查一下torch.cuda.is_available()返回的是不是True如果环境装的是CPU版本的PyTorch即使有显卡也用不上。解决重装CUDA版本的PyTorch注意版本必须和你的显卡驱动匹配。可以用nvidia-smi查看驱动支持的CUDA版本然后去PyTorch官网选对应的安装命令。装完之后在代码里加上torch.device(cuda if torch.cuda.is_available() else cpu)并把模型和输入tensor都to(device)。5.2 现象检测模型对特定角度的脸漏检严重侧脸几乎检测不到原因训练数据里正脸样本占绝大多数模型没有学到足够多的侧脸特征。这个在开源数据集里很常见WIDER Face虽然数据量大但侧脸样本比例依然偏低。解决如果你只是做演示可以在数据增强里加上random_rotate和random_perspective把角度变化范围加大。用Yolov5自带的超参数文件在hyp.scratch.yaml里把hsv_h、hsv_s这些颜色增强参数适当调大让模型见过更多样的输入。如果是实际项目老老实实补充侧脸数据重新标注。5.3 现象表情识别在真实摄像头下准确率暴跌和测试集表现差距巨大原因训练数据来自网络图片和摄像头采集的人脸在光照、角度、分辨率上有分布偏移。这是一个典型的“域差异”问题。解决我一般会在部署前做一步简单的图像预处理统一——把摄像头帧里的人脸区域做直方图均衡化让光照分布更接近训练集。另外把confidence阈值适当调低因为域偏移会让模型输出的概率整体偏低阈值太高会导致大量表情被判成“正常”。5.4 现象模型能检测到人的位置但边界框抖动剧烈行为判定不稳定原因视频流帧间检测框的位置和大小波动大导致行为判定的输入不连贯。Yolov5本身的输出就对小目标比较敏感稍微模糊一帧框就飘了。解决在业务判断层之前加一个简单的卡尔曼滤波或者EMA平滑。EMA的做法是当前帧检测框中心和上一帧平滑结果做加权平均权重取0.7的新帧比例。这个方法实现只要三行代码但能显著减少抖动代价是检测框会稍微滞后于真实位置对人脸识别无影响对行为检测影响可接受。5.5 现象视频流推理占用显存持续增长跑十几分钟后程序被OOM杀掉原因视频处理循环里没有释放中间tensor梯度计算图累积。推理模式必须包在torch.no_grad()里很多人训练代码写惯了会忘记加。解决在detect.py的推理循环外面加上torch.no_grad()循环内部每次处理的帧如果用到了numpy数组转tensor记得在不用之后del掉。另外opencv的视频捕获对象VideoCapture用完之后要调用release()释放否则摄像头资源一直被占着。如果是Docker部署记得给容器加--shm-size参数默认的64MB共享内存经常不够用。6. 进阶调优把自己的数据集接进来并加速推理6.1 自定义数据集的格式转换与训练你肯定不想一直用自带的模型接自己的数据集是迟早的事。Yolov5训练自己的数据只需要两个东西标注文件和配置文件。标注文件用YOLO格式——每个bbox一行格式是class_id x_center y_center width height坐标归一化到0-1。如果你手里的数据是VOC格式的XML标注需要先转成TXT格式网上有现成脚本你也可以自己写一个核心逻辑就是解析XML里的xmin、ymin、xmax、ymax节点除以图片宽度和高度得到归一化坐标。训练之前把数据集目录结构整理好dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── dataset.yamldataset.yaml文件里写上类别数和类别名然后用train.py启动训练。如果你的数据集只有几百张图建议用yolov5s模型配合迁移学习把预训练权重带上冻结backbone的前几层只训练后面的检测头。这样即使数据量不大收敛效果也远比从零训练好。我实测过500张人脸数据集yolov5s训练50个epoch在测试集上的mAP能达到0.82够演示用。6.2 推理加速TensorRT导出与批量检测如果你的机器有NVIDIA显卡Yolov5支持直接导出TensorRT引擎推理速度能提升三到五倍。导出命令很简单python export.py --weights weights/face_detect.pt --include engine --device 0 --imgsz 640导出TensorRT引擎之后detect.py里会自动识别.engine后缀的文件并加载。注意导出的引擎是绑定显卡型号的换一台显卡需要重新导出。此外如果你检测的视频流分辨率不是640x640不需要改输入尺寸Yolov5会自动缩放再送进模型不需要你手动预处理——这个细节很多人不知道以为必须把帧到640x640才能检测实际上源码里的letterbox函数会自动处理。6.3 多线程并行推理与最终验证一个能明显提升系统流畅度的做法是把摄像头读取和模型推理放两个线程读取线程只管把帧丢进队列推理线程从队列取帧检测。这样能避免每帧等待摄像头I/O的时间让GPU一直处于忙碌状态。源码里没有实现这个优化你可以用Python的queue和threading模块加上去逻辑不算复杂。最后我每次部署这个项目都会强制走一遍完整流程先确认CUDA可用再确认权重文件存在然后跑一帧静态图片验证检测链路最后接视频流验证时序逻辑。任何一步失败都先解决再往下走不要急着上摄像头。希望这份拆解能帮你少走弯路顺利把项目跑起来。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。