1. 项目概述:当YOLOv5遇上口罩检测
去年在商场门口亲眼目睹保安和未戴口罩顾客的争执后,我萌生了开发智能口罩检测系统的想法。传统人工查验不仅效率低下,在高峰期更容易引发冲突。而基于YOLOv5的目标检测技术,配合PyTorch框架的灵活性,正好能解决这个问题。
这个项目本质上是在实时视频流中定位并分类人脸口罩佩戴状态,核心要解决三个问题:首先是如何处理不同光照条件下的人脸检测,其次是准确区分正确佩戴、错误佩戴和未佩戴三种状态,最后是保证在嵌入式设备上的推理速度。经过两个月的迭代,最终实现的系统在1080P分辨率下能达到32FPS的处理速度,准确率稳定在94%以上。
关键提示:YOLOv5虽然以速度快著称,但在小目标检测(如口罩边缘)上需要特殊处理,这是本项目最大的技术挑战
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境搭建与工具选型
2.1 硬件配置方案
我的开发环境组合经历了三次调整:
- 初始阶段:RTX 3060笔记本(6GB显存)+ 16GB内存
- 训练阶段:阿里云GN6v实例(NVIDIA V100 32GB)
- 部署阶段:Jetson Xavier NX
对于想复现的朋友,建议至少准备:
- GPU:NVIDIA GTX 1660以上(4GB显存起步)
- CPU:4核以上(用于数据预处理)
- 内存:8GB(最低要求,16GB更佳)
踩坑记录:最初在RTX 3060上直接跑官方预训练模型时,由于CUDA 12.1与PyTorch 1.12的兼容性问题,导致显存溢出。解决方案是降级到CUDA 11.3 + PyTorch 1.10组合。
2.2 软件环境配置
通过conda创建隔离环境是最稳妥的方案:
bash复制conda create -n maskdetect python=3.8
conda activate maskdetect
pip install torch==1.10.0+cu113 torchvision==0.11.1+cu113 -f https://download.pytorch.org/whl/torch_stable.html
YOLOv5的安装要注意分支选择:
bash复制git clone -b v6.0 https://github.com/ultralytics/yolov5
cd yolov5
pip install -r requirements.txt
国内用户推荐替换pip源:
bash复制pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
3. 数据工程实战
3.1 数据集构建
优质的数据集需要覆盖:
- 人种多样性(亚洲/欧洲/非洲面孔)
- 光照条件(强光/弱光/逆光)
- 遮挡情况(眼镜/围巾/手势遮挡)
- 角度变化(俯拍/仰拍/侧脸)
我融合了三个公开数据集:
- MAFA(包含3.5万张遮挡人脸)
- Moxa3K(专门针对口罩检测)
- 自采集的2000张超市监控画面
标注格式采用YOLOv5标准:
code复制<object-class> <x_center> <y_center> <width> <height>
其中类别定义为:
- 0: 正确佩戴口罩
- 1: 错误佩戴口罩(如露出鼻子)
- 2: 未佩戴口罩
3.2 数据增强策略
在data/hyps/hyp.scratch-low.yaml中调整:
yaml复制hsv_h: 0.015 # 色调增强幅度
hsv_s: 0.7 # 饱和度增强
hsv_v: 0.4 # 明度增强
degrees: 10 # 旋转角度范围
translate: 0.1 # 平移比例
scale: 0.5 # 缩放范围
shear: 0.0 # 剪切变换
特别增加了针对口罩的专属增强:
- 随机添加模拟呼吸导致的口罩褶皱
- 生成眼镜反光效果
- 模拟口罩带断裂的局部遮挡
4. 模型训练与优化
4.1 模型选型对比
测试了YOLOv5各版本在口罩检测上的表现:
| 模型版本 | 参数量(M) | mAP@0.5 | FPS(3060) |
|---|---|---|---|
| yolov5n | 1.9 | 0.87 | 142 |
| yolov5s | 7.2 | 0.91 | 98 |
| yolov5m | 21.2 | 0.93 | 67 |
| yolov5l | 46.5 | 0.94 | 43 |
最终选择yolov5s作为基础模型,在速度和精度间取得平衡。
4.2 关键训练参数
启动训练的命令示例:
bash复制python train.py --img 640 --batch 16 --epochs 100 --data mask.yaml --cfg models/yolov5s.yaml --weights yolov5s.pt --hyp data/hyps/hyp.scratch-low.yaml
几个必须调整的参数:
- --img-size:根据摄像头分辨率设置,建议不小于640
- --batch-size:显存允许下尽可能大(需为8的倍数)
- --rect:启用矩形训练节省显存
4.3 注意力机制改进
在models/yolov5s.yaml中添加CBAM模块:
yaml复制backbone:
[[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
[-1, 1, CBAM, [128]], # 1-P2/4
[-1, 3, C3, [128]],
...]
改进后的模型在小目标检测上mAP提升2.3%,但推理速度下降约8%。
5. 部署与性能优化
5.1 TensorRT加速
转换到TensorRT引擎的完整流程:
bash复制python export.py --weights runs/train/exp/weights/best.pt --include engine --device 0 --half
关键优化点:
- 开启FP16模式:--half
- 动态轴设置:-d 1,3,640,640
- 对于Jetson设备需添加--workspace=8
5.2 边缘设备适配
在Jetson Xavier NX上的部署技巧:
- 安装JetPack 4.6.1(包含CUDA 10.2)
- 使用torch-1.10.0-cp36-cp36m-linux_aarch64.whl
- 设置功率模式:
bash复制sudo nvpmodel -m 2 # 10W模式
sudo jetson_clocks # 强制最大频率
实测性能:
- 原始PyTorch模型:9 FPS
- TensorRT优化后:22 FPS
- 开启DLA:28 FPS
6. 实际应用中的问题排查
6.1 典型误检场景
收集到的TOP3错误案例:
- 手持口罩靠近脸部被识别为佩戴
- 络腮胡子区域误判为口罩
- 深色围巾边缘检测为口罩带
解决方案:
- 增加负样本(手持口罩的特写)
- 在推理后添加基于关键点的验证:
python复制def check_mask_position(nose_x, nose_y, mask_bbox):
# 计算鼻子是否在口罩区域内
return mask_bbox[0] < nose_x < mask_bbox[2] and \
mask_bbox[1] < nose_y < mask_bbox[3]
6.2 光照补偿方案
针对低光照环境的改进:
python复制def adaptive_gamma_correction(img):
# 基于局部亮度的自适应伽马校正
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
l, a, b = cv2.split(lab)
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
limg = clahe.apply(l)
return cv2.cvtColor(cv2.merge((limg,a,b)), cv2.COLOR_LAB2BGR)
7. 系统集成与效果展示
完整的处理流水线包含:
- 视频流获取(支持RTSP/USB摄像头)
- 多线程预处理(缩放+归一化)
- 基于队列的批推理
- 后处理(NMS+业务逻辑)
- 可视化输出
核心代码结构:
python复制class MaskDetectionSystem:
def __init__(self):
self.model = load_yolov5_model()
self.tracker = StrongSORT()
def process_frame(self, frame):
detections = self.model(frame)
tracks = self.tracker.update(detections)
return apply_business_rules(tracks)
实测在超市入口场景下,相比人工查验:
- 通过率提升40%
- 漏检率低于2%
- 平均等待时间缩短65%
