1. 项目背景与意义
在公共场所禁烟已经成为社会共识,但传统的人工巡查方式存在效率低下、成本高昂等问题。作为一名计算机视觉方向的实践者,我注意到目标检测技术在安防、零售等领域的成功应用,却鲜有针对吸烟行为的专门研究。这个毕业设计项目正是基于YOLOv5算法,构建了一套高效的吸烟行为检测系统。
从技术角度看,这个选题的价值在于:
- 填补了特定场景下的技术空白
- 验证了轻量级模型在行为检测中的可行性
- 为类似场景(如安全帽检测、口罩检测)提供了技术参考
我选择YOLOv5s作为基础模型,主要考虑到它在精度和速度上的平衡。实测在GTX 1660Ti显卡上,推理速度能达到45FPS,完全满足实时监控的需求。
2. 系统架构设计
2.1 整体技术路线
系统采用经典的"数据采集→模型训练→部署应用"流程:
code复制数据采集 → 数据标注 → 模型选型 → 训练优化 → 模型导出 → 应用部署
2.2 关键技术选型
YOLOv5s的四大优势:
- 模型轻量化:仅14MB大小
- 多平台支持:可导出为ONNX/TensorRT等格式
- 训练友好:自带超参数进化算法
- 社区支持:活跃的GitHub社区
对比其他方案:
| 方案 | mAP@0.5 | 参数量 | FPS |
|---|---|---|---|
| Faster R-CNN | 0.82 | 41.3M | 12 |
| SSD | 0.78 | 26.5M | 35 |
| YOLOv5s | 0.85 | 7.2M | 45 |
3. 数据集构建
3.1 数据采集策略
由于缺乏现成的吸烟数据集,我们采用多源采集方案:
- 网络爬虫:通过关键词获取候选图片
- 视频抽帧:从监控视频中提取典型场景
- 模拟拍摄:组织志愿者配合采集
最终构建的数据集包含:
- 训练集:4000张(80%)
- 验证集:500张(10%)
- 测试集:500张(10%)
3.2 数据标注规范
使用LabelImg进行标注时,制定了严格的标注准则:
- 吸烟动作判定标准:香烟与嘴部距离<50像素
- 遮挡处理:可见部分>30%才标注
- 多角度覆盖:包含正面、侧面、仰角等
标注文件示例:
xml复制<annotation>
<object>
<name>smoke</name>
<bndbox>
<xmin>256</xmin>
<ymin>189</ymin>
<xmax>312</xmax>
<ymax>245</ymax>
</bndbox>
</object>
</annotation>
4. 模型训练优化
4.1 超参数配置
在smoke.yaml中关键配置:
yaml复制nc: 1 # 单类别检测
depth_multiple: 0.33 # 控制网络深度
width_multiple: 0.50 # 控制通道数
训练命令示例:
bash复制python train.py --img 640 --batch 16 --epochs 300 --data smoke.yaml --cfg yolov5s.yaml --weights yolov5s.pt
4.2 数据增强策略
采用Mosaic+MixUp组合增强:
- Mosaic:四图拼接增强小目标检测
- MixUp:图像混合提升泛化能力
- HSV调整:模拟不同光照条件
增强效果对比:
| 增强方式 | mAP@0.5 | 推理速度 |
|---|---|---|
| 基础增强 | 0.82 | 48FPS |
| Mosaic | 0.85 | 45FPS |
| Mosaic+MixUp | 0.87 | 43FPS |
4.3 训练技巧
- 冻结训练:前50epoch冻结骨干网络
- 自动锚框:通过k-means聚类优化anchor
- 早停机制:连续10epoch无提升则停止
训练曲线分析:
- 损失函数在100epoch后趋于稳定
- mAP在200epoch达到峰值
- 最佳模型保存在epoch 245
5. 关键代码解析
5.1 模型结构定义
YOLOv5s的核心结构:
python复制# backbone
backbone:
[[-1, 1, Focus, [64, 3]], # 0-P1/2
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
[-1, 3, BottleneckCSP, [128]],
...]
# head
head:
[[-1, 1, Conv, [512, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
...]
5.2 检测逻辑实现
检测流程关键代码:
python复制def detect():
# 图像预处理
img = letterbox(img0, new_shape=imgsz)[0]
img = img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB
img = np.ascontiguousarray(img)
# 模型推理
pred = model(img, augment=augment)[0]
# NMS处理
pred = non_max_suppression(pred, conf_thres, iou_thres)
# 结果解析
for det in pred:
if len(det):
det[:, :4] = scale_coords(img.shape[2:], det[:, :4], img0.shape).round()
5.3 视频流处理
实时检测实现方案:
python复制cap = cv2.VideoCapture(0) # 摄像头输入
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# 推理检测
results = model(frame)
# 渲染结果
cv2.imshow('Detection', render_frame(results))
if cv2.waitKey(1) == ord('q'):
break
6. 部署与优化
6.1 模型导出
转换为ONNX格式:
bash复制python export.py --weights runs/train/exp/weights/best.pt --img 640 --batch 1 --include onnx
6.2 性能优化技巧
- TensorRT加速:提升30%推理速度
- 半精度推理:减少显存占用
- 多线程处理:摄像头采集与推理分离
优化前后对比:
| 优化方式 | 显存占用 | FPS提升 |
|---|---|---|
| 原始模型 | 1.2GB | - |
| FP16推理 | 0.8GB | +15% |
| TensorRT | 0.6GB | +30% |
7. 常见问题解决
7.1 训练问题排查
问题1:损失不收敛
- 检查数据标注质量
- 调整初始学习率(建议0.01)
- 验证数据增强效果
问题2:过拟合
- 增加数据多样性
- 添加Dropout层
- 使用早停机制
7.2 部署问题
摄像头延迟高
python复制# 解决方案:启用多线程
from threading import Thread
class VideoStream:
def __init__(self, src=0):
self.stream = cv2.VideoCapture(src)
self.grabbed, self.frame = self.stream.read()
self.stopped = False
def start(self):
Thread(target=self.update, args=()).start()
return self
def update(self):
while not self.stopped:
self.grabbed, self.frame = self.stream.read()
8. 创新点与改进方向
8.1 项目创新
- 针对性的数据增强策略
- 优化anchor设置提升小目标检测
- 轻量化部署方案
8.2 后续优化
- 引入行为时序分析
- 添加人脸模糊保护
- 开发移动端应用
在实际测试中,系统在室内场景下准确率达到89%,室外复杂场景下为76%。通过调整检测阈值,可以在精度和召回率之间取得平衡。建议在实际部署时,根据具体场景调整以下参数:
- 置信度阈值:0.4-0.6
- IOU阈值:0.45-0.55
- 图像尺寸:640x640
