ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于YOLOv5的实时抽烟检测系统开发与优化

基于YOLOv5的实时抽烟检测系统开发与优化

1. 项目背景与核心价值

这个基于YOLO算法的抽烟行为检测系统,最初是我为电子信息工程专业毕业设计开发的实战项目。现在把完整代码和训练模型开源出来,特别适合计算机视觉入门者、需要快速完成毕设的同学,以及社区安防领域的开发者。

为什么选择抽烟检测这个方向?在商场、学校、工厂等公共场所,实时监测违规抽烟行为一直是安防管理的痛点。传统人工巡检效率低下,而基于深度学习的视觉检测方案能实现7×24小时自动化监控。经过对比测试,YOLO系列算法在检测速度和精度上达到了最佳平衡,特别适合部署在边缘计算设备。

2. 技术方案选型解析

2.1 为什么选择YOLO算法

在目标检测领域,我们对比了Faster R-CNN、SSD和YOLO三大主流架构:

算法类型检测速度(FPS)mAP精度硬件需求适用场景
Faster R-CNN5-778.8%高高精度静态图像
SSD22-2876.8%中平衡型应用
YOLOv5s45-5076.5%低实时视频流

实测数据显示,YOLOv5s在GTX 1060显卡上能达到48FPS的检测速度,完全满足实时监控需求。其单阶段检测架构避免了R-CNN系列的区域提议步骤,特别适合处理视频流数据。

2.2 模型轻量化改造

为适配边缘设备部署,我们对原生YOLOv5s做了三项优化:

  1. 通道剪枝:移除20%低贡献度的卷积通道
  2. 量化训练:采用QAT量化感知训练,将模型从FP32压缩到INT8
  3. 注意力机制:在Backbone末端添加SE模块

优化前后对比:

  • 模型体积:从27MB减小到9.8MB
  • 推理速度:从48FPS提升到63FPS
  • mAP精度:仅下降2.3个百分点

3. 数据集构建与标注

3.1 数据采集方案

我们采用多源数据融合策略:

  • 公开数据集:整合Smoke100K和Tobacco800
  • 自采视频:在10个不同场景拍摄200段监控视角视频
  • 数据增强:使用imgaug库实现:
    seq = iaa.Sequential([ iaa.Fliplr(0.5), # 水平翻转 iaa.GaussianBlur(sigma=(0, 1.0)), iaa.AdditiveGaussianNoise(scale=0.05*255) ])

最终构建的数据集包含:

  • 训练集:12,458张图像(含8,724张增强图像)
  • 验证集:1,856张图像
  • 测试集:2,103张图像

3.2 标注规范设计

采用专业标注工具LabelImg,制定严格标注规则:

  1. 吸烟动作判定标准:
    • 手持香烟且靠近口部
    • 可见烟雾呼出
    • 香烟长度≥15像素
  2. 遮挡处理:
    • 可见部分≥30%时标注
    • 多人重叠时标注最完整个体

4. 模型训练细节

4.1 超参数配置

关键训练参数经过网格搜索确定:

lr0: 0.01 # 初始学习率 lrf: 0.1 # 最终学习率倍数 momentum: 0.937 weight_decay: 0.0005 warmup_epochs: 3.0 batch_size: 32

使用余弦退火学习率策略:

def cosine_lr(epoch): return lr_min + 0.5*(lr_max-lr_min)*(1+math.cos(epoch/total_epoch*math.pi))

4.2 训练过程监控

采用WandB进行可视化监控,重点关注三个指标:

  1. Precision-Recall曲线
  2. Grad-CAM热力图
  3. 损失函数收敛情况

典型训练曲线显示:

  • box_loss在50epoch后稳定在0.08
  • obj_loss收敛到0.012
  • cls_loss保持在0.005以下

5. 部署实施方案

5.1 边缘设备适配

测试过的硬件平台包括:

  • Jetson Nano:18FPS
  • RK3588:32FPS
  • 树莓派4B+Intel神经棒:9FPS

部署时关键优化点:

// OpenVINO优化示例 auto network = ie.ReadNetwork("yolo.xml"); network.setBatchSize(1); ExecutableNetwork executable_network = ie.LoadNetwork(network, "GPU");

5.2 系统集成方案

提供三种接入方式:

  1. RTSP视频流处理
  2. USB摄像头直连
  3. 图片批量检测API

典型报警逻辑实现:

if smoke_detected: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") cv2.imwrite(f"alert_{timestamp}.jpg", frame) GPIO.output(buzzer_pin, GPIO.HIGH)

6. 实测性能分析

在测试集上获得的结果:

指标白天场景夜间场景遮挡场景
精确率89.2%83.7%76.5%
召回率85.1%79.3%68.9%
误报率/小时1.22.84.1

典型误报情况分析:

  • 手持细长物体(如笔、吸管)
  • 蒸汽/雾气干扰
  • 特殊角度的遮挡

7. 工程优化建议

7.1 模型微调技巧

当部署到新场景时,建议:

  1. 使用迁移学习微调最后10层
  2. 添加场景特定的负样本
  3. 调整NMS阈值:
    torch.hub.load('ultralytics/yolov5', 'custom', path='best.pt', nms_conf=0.4, # 默认0.25 nms_iou=0.6) # 默认0.45

7.2 部署避坑指南

常见问题解决方案:

  1. 内存泄漏:检查OpenCV的版本兼容性
  2. 帧率下降:禁用Ubuntu桌面动画效果
  3. 误报过高:增加温度传感器辅助判断

8. 扩展应用方向

本项目的技术框架可迁移到:

  1. 安全帽佩戴检测
  2. 危险区域入侵检测
  3. 工业操作规范检查

只需修改数据标注和输出层:

# 修改类别定义 nc = 2 # 新类别数 model.model[-1] = Detect(nc, anchors, [ch])

这个项目从构思到实现共耗时3个月,期间最大的收获是认识到工业场景的数据分布与公开数据集的显著差异。建议在实际部署前,务必采集目标场景的负样本进行针对性优化。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进