基于YOLOv5的实时口罩检测系统开发实战

发布时间:2026/7/4 12:38:38

基于YOLOv5的实时口罩检测系统开发实战 1. 项目概述与背景口罩检测系统在当前公共卫生场景下具有重要应用价值。作为一名长期从事计算机视觉开发的工程师我最近完成了一个基于YOLOv5和PyTorch的实时口罩检测系统能够在视频流中准确识别佩戴口罩和未佩戴口罩的人脸。这个项目从环境搭建到模型部署共耗时两周最终在测试集上达到了96.3%的mAP平均精度。选择YOLOv5作为基础框架主要基于三个考量首先它的推理速度能够满足实时性要求在RTX 3060上达到45FPS其次相比其他目标检测模型YOLOv5在小目标检测上表现更优最后其PyTorch实现使得模型调试和二次开发更加便捷。下面我将详细分享整个开发过程中的技术细节和实战经验。2. 开发环境配置2.1 基础环境搭建推荐使用Anaconda创建隔离的Python环境这能有效避免包版本冲突。以下是经过验证的稳定版本组合conda create -n yolo_mask python3.8 -y conda activate yolo_mask注意Python 3.8是目前与PyTorch生态兼容性最好的版本不建议使用3.9及以上版本以避免潜在的库兼容问题。对于PyTorch的安装需要根据显卡的CUDA版本选择对应安装命令。可以通过nvidia-smi命令查看CUDA版本。以下是常见版本的安装示例# CUDA 11.1 pip install torch1.9.0cu111 torchvision0.10.0cu111 torchaudio0.9.0 -f https://download.pytorch.org/whl/torch_stable.html # CUDA 10.2 pip install torch1.9.0cu102 torchvision0.10.0cu102 torchaudio0.9.0 -f https://download.pytorch.org/whl/torch_stable.html # 仅CPU pip install torch1.9.0cpu torchvision0.10.0cpu torchaudio0.9.0 -f https://download.pytorch.org/whl/torch_stable.html2.2 YOLOv5依赖安装从官方仓库克隆最新代码并安装依赖git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt安装过程中常见问题及解决方案OpenCV报错如果遇到libGL.so缺失错误在Ubuntu上运行sudo apt install libgl1PyTorch版本冲突确保torch版本与CUDA版本匹配必要时先卸载原有版本pip uninstall torch torchvision权限问题在Linux系统下建议使用--user参数或虚拟环境3. 数据准备与标注3.1 数据集构建优质的数据集是模型性能的基石。我们采用以下两种方式构建口罩数据集公开数据集MAFAMasked Face数据集包含35,806张带标注图像自采集数据使用网络爬虫获取1,200张多样化场景图片数据集目录结构应采用YOLOv5标准格式dataset/ ├── images/ │ ├── train/ # 训练集图片 │ └── val/ # 验证集图片 └── labels/ ├── train/ # 训练集标签YOLO格式 └── val/ # 验证集标签3.2 数据标注规范使用LabelImg工具进行标注时需注意标注框应紧贴人脸下巴和额头保留适当边缘对于部分遮挡情况仍标注完整人脸区域类别定义with_mask正确佩戴口罩without_mask未佩戴口罩mask_weared_incorrect口罩佩戴不规范标注完成后需要将VOC XML格式转换为YOLO格式。转换脚本核心逻辑def convert(size, box): dw 1./size[0] dh 1./size[1] x (box[0] box[1])/2.0 y (box[2] box[3])/2.0 w box[1] - box[0] h box[3] - box[2] x x*dw w w*dw y y*dh h h*dh return (x,y,w,h)3.3 数据增强策略在data.yaml中配置Mosaic和MixUp增强train: ../dataset/images/train val: ../dataset/images/val nc: 3 names: [with_mask, without_mask, mask_weared_incorrect] # 数据增强参数 augment: hsv_h: 0.015 # 色调增强幅度 hsv_s: 0.7 # 饱和度增强幅度 hsv_v: 0.4 # 明度增强幅度 degrees: 10 # 旋转角度范围 translate: 0.1 # 平移比例 scale: 0.5 # 缩放比例 shear: 0.0 # 剪切幅度 perspective: 0.0 # 透视变换 flipud: 0.0 # 上下翻转概率 fliplr: 0.5 # 左右翻转概率 mosaic: 1.0 # Mosaic概率 mixup: 0.2 # MixUp概率4. 模型训练与调优4.1 训练参数配置启动训练的核心命令python train.py --img 640 --batch 16 --epochs 100 --data data.yaml \ --weights yolov5s.pt --device 0 --name mask_detection \ --hyp data/hyps/hyp.scratch-low.yaml关键参数解析--img 640输入图像尺寸保持与推理时一致--batch 16批次大小根据GPU显存调整11G显存可支持16--epochs 100训练轮次建议50-300之间--hyp超参数配置文件控制学习率等关键参数4.2 学习率策略优化在hyp.scratch-low.yaml中调整关键训练参数lr0: 0.01 # 初始学习率 lrf: 0.2 # 最终学习率 lr0 * lrf momentum: 0.937 # SGD动量 weight_decay: 0.0005 # 权重衰减 warmup_epochs: 3.0 # 学习率预热轮次 warmup_momentum: 0.8 # 预热阶段动量 warmup_bias_lr: 0.1 # 预热阶段偏置学习率实战经验当验证集指标波动较大时尝试将lr0降低到0.001同时增加warmup_epochs到54.3 模型架构调整对于口罩检测这种相对简单的任务可以精简模型结构。修改models/yolov5s.yaml# YOLOv5 backbone backbone: # [from, number, module, args] [[-1, 1, Focus, [64, 3]], # 0-P1/2 [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 [-1, 3, C3, [128]], # 2 [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 [-1, 6, C3, [256]], # 4 [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 [-1, 9, C3, [512]], # 6 [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 [-1, 3, C3, [1024]], # 8 [-1, 1, SPPF, [1024, 5]], # 9 ] # YOLOv5 head head: [[-1, 1, Conv, [512, 1, 1]], [-1, 1, nn.Upsample, [None, 2, nearest]], [[-1, 6], 1, Concat, [1]], # cat backbone P4 [-1, 3, C3, [512, False]], # 13 [-1, 1, Conv, [256, 1, 1]], [-1, 1, nn.Upsample, [None, 2, nearest]], [[-1, 4], 1, Concat, [1]], # cat backbone P3 [-1, 3, C3, [256, False]], # 17 (P3/8-small) [-1, 1, Conv, [256, 3, 2]], [[-1, 14], 1, Concat, [1]], # cat head P4 [-1, 3, C3, [512, False]], # 20 (P4/16-medium) [-1, 1, Conv, [512, 3, 2]], [[-1, 10], 1, Concat, [1]], # cat head P5 [-1, 3, C3, [1024, False]], # 23 (P5/32-large) [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) ]主要优化点减少C3模块的重复次数以降低计算量调整特征图通道数在浅层保留更多细节信息修改Anchor尺寸适配人脸比例5. 模型推理与部署5.1 实时检测实现核心检测代码解析import cv2 import torch import numpy as np # 模型加载 device torch.device(cuda:0 if torch.cuda.is_available() else cpu) model torch.load(weights/best.pt, map_locationdevice)[model].float() model.to(device).eval() # 视频流处理 cap cv2.VideoCapture(0) # 0表示默认摄像头 while True: ret, frame cap.read() if not ret: break # 图像预处理 img cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) img cv2.resize(img, (640, 640)) img np.transpose(img, (2, 0, 1)) # HWC to CHW img np.expand_dims(img, axis0) # 添加batch维度 img torch.from_numpy(img).to(device).float() / 255.0 # 推理 with torch.no_grad(): pred model(img)[0] # NMS后处理 pred non_max_suppression(pred, conf_thres0.5, iou_thres0.5) # 结果可视化 for det in pred: if det is not None and len(det): det[:, :4] scale_coords(img.shape[2:], det[:, :4], frame.shape).round() for *xyxy, conf, cls in det: label f{model.names[int(cls)]} {conf:.2f} cv2.rectangle(frame, (int(xyxy[0]), int(xyxy[1])), (int(xyxy[2]), int(xyxy[3])), (0, 255, 0), 2) cv2.putText(frame, label, (int(xyxy[0]), int(xyxy[1])-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) cv2.imshow(Mask Detection, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()5.2 性能优化技巧TensorRT加速python export.py --weights best.pt --include engine --device 0转换后的TensorRT引擎可提升2-3倍推理速度多线程处理from threading import Thread class VideoStream: def __init__(self, src0): self.stream cv2.VideoCapture(src) self.grabbed, self.frame self.stream.read() self.stopped False def start(self): Thread(targetself.update, args()).start() return self def update(self): while not self.stopped: self.grabbed, self.frame self.stream.read() def read(self): return self.frame def stop(self): self.stopped True模型量化model model.half() # FP16量化6. 常见问题与解决方案6.1 训练阶段问题问题1Loss震荡不收敛检查学习率是否过大适当降低lr0验证数据标注质量可能存在错误标注尝试增加warmup_epochs让模型平稳进入训练问题2验证集mAP低于训练集可能是过拟合增加数据增强强度在hyp.yaml中调大weight_decay值早停策略当验证指标连续3个epoch不提升时停止训练6.2 推理阶段问题问题1漏检率高降低conf_thres如从0.5调到0.3检查训练数据是否覆盖了各种光照和角度场景增加输入图像分辨率从640提高到1280问题2误检多提高conf_thres如从0.5调到0.6增加NMS的iou_thres如从0.5调到0.7在困难样本上追加训练数据6.3 部署问题问题1GPU内存不足减小batch_size使用--half进行FP16推理尝试更小的模型变体如yolov5n问题2延迟高使用TensorRT加速降低输入分辨率采用多线程流水线处理7. 项目扩展方向在实际部署中我们还可以考虑以下增强功能人数统计结合跟踪算法实现实时人数统计from collections import defaultdict track_history defaultdict(lambda: []) for box in detections: track_id get_track_id(box) # 使用DeepSORT等算法 track_history[track_id].append(box)报警系统检测到未戴口罩时触发声音警报import pygame pygame.mixer.init() alert_sound pygame.mixer.Sound(alert.wav) if without_mask in detected_classes: alert_sound.play()云端部署使用Flask构建Web服务from flask import Flask, request, jsonify app Flask(__name__) app.route(/detect, methods[POST]) def detect(): file request.files[image] img cv2.imdecode(np.frombuffer(file.read(), np.uint8), cv2.IMREAD_COLOR) # 执行检测逻辑 return jsonify(results) if __name__ __main__: app.run(host0.0.0.0, port5000)经过实际测试这个系统在室内场景下能达到98%的准确率室外复杂场景约92%。最大的收获是认识到数据质量对模型性能的决定性影响——后期我们花费了60%的时间在数据清洗和增强上这比调参带来的提升显著得多。

相关新闻