news 2026/9/8 19:15:48

基于YOLOv5的火焰烟雾检测:源码数据集与实战部署指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于YOLOv5的火焰烟雾检测:源码数据集与实战部署指南

简介:面向住宅、工业园区、森林、加油站等场景的火焰与烟雾检测需求,这份基于YOLOv5的深度学习资源提供了完整源码与配套数据集,适合具备一定PyTorch基础的目标检测学习者、安全监控开发人员以及相关课程设计团队使用。包内包含约2000个文件,其中1900多张JPG图像与对应txt标注文件构成可直接投入训练的数据集,图像覆盖多种室内外环境与光照条件;另有yaml训练配置、Python脚本、pyc缓存、预训练pt权重、Shell辅助脚本等,可支撑从数据准备、模型训练到推理部署的完整流程。压缩包还附带Dockerfile、Jupyter Notebook示例、安装说明docx文档和演示视频,能够显著降低环境配置门槛,方便用户对照说明快速复现火焰烟雾识别效果。数据集内样本覆盖白天、夜间等不同时段,有助于增强模型鲁棒性;已有12849人学习下载。整体结构清晰、组件齐全,可作为智慧安防、园区监测等项目的实验基础或二次开发蓝本,工程实用价值较高。 如果你做的是安防、消防或者园区巡检这类视觉项目,大概率会碰到一个尴尬的局面:网上搜“火焰检测”,看到的论文一套一套的,但真正能下载下来直接跑的工程少之又少。我前阵子把一套实际部署过的方案重新整理了一遍,留下了yolov5火焰和烟雾源码和数据集.zip这个压缩包,里面YOLOv5的完整源码、训练脚本、已经标注好的火焰烟雾数据集都在,解压后既能直接训练,也能对摄像头视频流做实时推理。这篇文章就围绕这套东西展开,把火焰烟雾为什么难检测、数据集该怎么看、训练时怎么调参、部署后怎么处理误报,从头到尾讲清楚。

1. 火焰和烟雾检测的特殊性:为什么通用目标检测模型做不好这件事

1.1 火焰和烟雾在视觉上“反常规”的原因

先解释一个很多人会忽略的问题:火焰和烟雾不是普通目标。普通目标检测里,行人、车辆、水杯、桌子,它们都有相对稳定的轮廓、固定的纹理和可预测的尺度范围。火焰正好反过来,它时刻在跳动,边缘是抖动的,内部颜色从红到黄到白一直渐变,同一个火焰在不同曝光条件下拍出来的样子差别非常大。烟雾更麻烦,它是半透明的,背景会透过烟雾显示出来,边缘几乎不存在,你让标注员去画一个烟雾的框,框太大会把背景包进去,框太小又会切断烟雾主体。这种目标特性决定了,直接用通用检测模型不做针对性调整,训练起来会异常吃力。

还有尺度问题。火灾早期,火焰和烟雾往往只占据画面的很小一部分,尤其是森林防火、园区高点监控这种场景,一个烟点在1080P画面里可能只有十几个像素;可一旦火势蔓延,整个画面又都是目标。这种极端尺度跨度,和COCO数据集里猫啊狗啊那种“目标占比相对稳定”的分布完全不同。所以很多人在自己数据集上跑出来的模型,检测普通目标时挺准,一到火焰烟雾上就出现大量漏检,核心原因就在这里:模型对“目标长什么样”的先验认知,和火焰烟雾的实际情况不匹配。

另一个维度是时间信息。单看一张静态图,一个红色灯光和一小团火焰很难区分;但放到视频里,火焰会闪烁,烟雾会缓慢扩散,这些动态特征才是判断关键。YOLOv5本身是单帧检测器,不擅长利用时序信息,所以单靠模型本身很难消除所有误报,必须通过后处理逻辑去弥补。这一点在后面的部署环节我会详细展开。

1.2 这个项目的数据与标注设定

这个压缩包里的数据集,通常包含两部分:图片文件(images)和对应的标签文件(labels),并且已经划分好了训练集、验证集和测试集。类目一般就两个:火焰(fire)和烟雾(smoke)。YOLO格式的标签长这样:每一行代表一个目标框,格式是类别id 中心点x 中心点y 框宽 框高,坐标值都做了归一化,范围在0到1之间。

datasets/fire_smoke/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yaml

data.yaml里指定了类别名称和图片路径,训练前一定要确认里面的路径和你本地的实际目录一致,不然会报文件找不到。

关于标注标准,我要特别提醒一点:火焰的框尽量框住“可见火焰区域”,不要为了把火苗根部一起包进去就把框向下拉得很大,那样会让模型学到一堆无效背景;烟雾的框则要框住“肉眼可辨的浓烟主体”,边缘那层很淡的气体不要硬框,否则标注噪声会直接传导给模型。拿到压缩包后,我强烈建议你写个小脚本,把标注画回图片上看一看,检查框是否贴合。如果发现标注框明显偏移,宁可先剔除这些样本,也不要让模型去学脏数据。

我自己的习惯是:跑训练前至少抽5%的图片做人工目检,尤其是验证集。验证集标注质量直接决定了mAP能不能正确反映模型好坏,这一步值得花时间。

2. 拿到压缩包后的第一件事:数据检查和环境准备

2.1 先看数据分布,再动手训练

很多拿到源码和数据集的人,第一反应是直接运行python train.py。我的建议是别急,先花十几分钟看数据。用脚本统计一下类别分布、每张图的平均目标数、边界框的尺寸分布。火焰烟雾数据集最常见的两个问题:一是类别不均衡,火多烟少或者反过来;二是某些图片是网上随手扒下来的低分辨率图,训练前没有清洗。如果类别分布差异很大,后续训练时可以通过调整采样权重或者针对性增广来缓解,但你得先知道问题存在。

另一个值得做的检查是标签重合度和空标签。数据集中可能会混入个别没有标注文件的图片,YOLOv5支持把它们作为背景参与训练,但数量上要控制,否则会让模型过度偏向“什么都不检测”。如果你发现背景图占比超过一半,建议先剔除一部分。

清洗完之后,再确认数据目录和data.yaml中的路径一致,把路径改成绝对路径或者项目内相对路径都可以,但别留着别人电脑上的旧路径。这一步看似琐碎,实际能帮你省掉大量排查时间。

2.2 环境配置:Python版本、依赖和CUDA问题

环境配置是初学者劝退重灾区。这套源码建议用 Python 3.8 到 3.10 之间的版本,太新的Python版本容易遇到某些依赖库还没有兼容轮子。用conda建一个独立环境最省心:

conda create -n fire python=3.9 conda activate fire cd yolov5-fire-smoke pip install -r requirements.txt

GPU环境下的头号问题是torch和CUDA版本不匹配。装完依赖后,先用python -c "import torch; print(torch.cuda.is_available())"确认一下。如果输出False,说明torch的CUDA版本不对,或者显卡驱动版本太低,需要根据你的CUDA版本重新安装对应的torch。CPU环境也不是不能跑,训练速度会慢得离谱,建议直接把输入分辨率降到512甚至416,模型换成yolov5nyolov5s

还有一个小坑:依赖安装时opencv-python如果和系统自带的libGL冲突,import时就会报libGL.so.1找不到。解决办法是apt-get install -y libgl1(Linux环境),或者直接装opencv-python-headless。这些都是常见的环境问题,遇到了不用慌,搜一下报错信息,基本都有现成答案。

3. 训练全流程拆解:从预训练权重到收敛判断

3.1 超参数怎么定才不浪费算力

先给一套最稳妥的起步配置:模型选yolov5s,输入分辨率--img 640,批大小根据显存来,8G显存就--batch 16,12G以上可以到32。训练轮数先跑150轮,数据量小就加到300轮。下面的命令可以直接用:

python train.py --data datasets/fire_smoke/data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 150 \ --cache

--cache的作用是把图片一次性加载到内存里,省去每轮训练反复读盘的耗时,前提是你的内存够用。默认权重yolov5s.pt是官方在COCO上预训练的,加载它做迁移学习,网络底层的边缘、颜色、纹理特征对火焰烟雾依然有效,比自己从头训练收敛快得多。

学习率通常不用刻意调,0.01的默认值对自定义数据集基本适用。但如果训练刚开始loss就爆掉,或者验证集指标乱跳,把hyp.scratch-low.yaml里的lr0改成0.005再试。另外建议加上--cos-lr,让学习率按余弦曲线衰减,我实测对小数据集更稳定。

显存不够时,优先减小batch,而不是减小输入分辨率。火焰烟雾的小目标多,分辨率降太多会直接牺牲召回率。如果想让训练更稳,可以先冻结前10层微调50轮,再全量训练,这种两阶段方式在数据量不足时效果比较明显。

3.2 看训练曲线,而不是只看mAP

训练结束后去runs/train/expN目录,重点看results.png。这张图会画出box_lossobj_losscls_loss三类loss的下降曲线,以及验证集上的精确率、召回率、mAP。模型是否收敛,标准是loss降到平台期、不再明显波动,同时mAP@0.5还在缓慢上升。

有一个判断技巧:如果训练loss一直降,但验证loss在某个点后开始回升,说明过拟合了,这时模型在训练集上学到了太多无关细节,对现场新场景的泛化会变差。解决办法是提前停止训练,或者增加增广、减小模型复杂度。

火焰烟雾任务的mAP@0.5通常能跑到0.85以上,但mAP@0.5:0.95会明显偏低,这是烟雾边界模糊导致的正常现象,不用太焦虑。这个指标对边框的贴合程度极其敏感,而烟雾本身就很难做到精确框定。判断模型好坏,最终还是要靠视频实测。

3.3 针对火焰烟雾的小目标改进

如果小目标漏检严重,有几个提升手段。首先是输入分辨率,--img 960甚至--img 1280对小目标召回帮助显著,代价是推理速度变慢、显存占用上升。其次是--multi-scale多尺度训练,让模型在不同分辨率下都能适应目标尺寸的变化。

训练日志里如果出现autoanchor分析锚框的环节,可以多看两眼。火焰和烟雾的长宽比和COCO里的目标差异很大,重新计算锚框有时能带来几个点的提升。YOLOv5训练时默认会自动分析锚框,不需要手动干预。

数据增广方面,YOLOv5默认开启的Mosaic、HSV扰动对火焰烟雾非常有用。火焰在不同光照条件下色差极大,HSV色相饱和度扰动可以模拟这种变化,增强模型鲁棒性。旋转增广要少加,火苗和烟雾基本是向上的,旋转角度过大会制造出不真实的训练样本。

4. 推理实测中的误报与漏报:原因分析和完整排查链路

4.1 先跑通视频/摄像头识别闭环

训练完拿到best.pt,第一步是把视频推理跑通:

python detect.py --weights runs/train/exp/best.pt \ --source 0 \ --conf 0.35

--source 0表示读取本机摄像头,也可以换成视频文件路径。--conf是置信度阈值,低于这个值的结果会被过滤掉。如果你要在自己的业务代码里集成,一般逻辑是:用cv2.VideoCapture读取视频帧,把帧交给模型推理,再把检测结果画到帧上。YOLOv5的接口封装得很干净,调用model(frame)后,返回的results.xyxy[0]就是检测框坐标、置信度和类别ID。

视频流处理的性能问题上,一个常用优化是“跳帧”:每处理一帧,间隔两三帧再做一次检测,中间那些帧直接沿用上一次的检测结果。火焰烟雾不像行人那样在画面中突然消失,跳帧对检测实时性影响很小,但可以把处理帧率提升好几倍。如果还是卡,就用多线程把视频解码和模型推理拆开,解码线程持续往队列里塞帧,推理线程从队列取帧处理,避免解码时间阻塞推理。

4.2 误报漏报的主要原因

部署到真实场景后,最折磨人的不是模型跑不起来,而是报警满天飞。我做过的项目里,误报和漏报的核心原因大致可以归成几类:

现象常见原因解决方向
夕阳、红色灯箱、车尾灯被识别成火焰火焰的颜色特征太明显,模型学到的是“红色发光物”加入时序闪烁判断,或检查区域颜色分布和运动特征
白色水蒸气、雾被识别成烟雾纹理半透明,和烟雾视觉相似利用浓度变化和运动方向过滤
远处小火苗、早期烟点漏掉目标像素太少,特征不明显提高输入分辨率,增加小目标样本
大火浓烟下目标互相遮挡目标大量重叠,框重叠严重多尺度训练,增加高密度场景数据

其中误报的杀伤力最大。一个现场日误报几十次,值班人员很快就会麻痹,等真火情出现时反而没人理。所以降低误报,优先级高于提高召回率。

4.3 一次真实的排查过程:夜间灯光误报

我做一个园区高点监控项目时,系统上线第一天晚上就频繁报警。把报警截图导出来一看,全是红颜色的灯箱和车尾灯。当时的第一反应是调高置信度阈值,从0.3提到0.5,效果确实有,但漏报率也跟着上来,一些远处的小烟点被过滤掉了。这说明单靠阈值解决不了问题。

第二步,增加时序逻辑。火焰在视频中会闪烁,真实火焰的信号不会静态不变。我在推理层加了一个滑动窗口:同一位置连续5帧里至少3帧检测到火焰,才触发报警。实现起来不难:

# 简化的时序确认逻辑 history = deque(maxlen=5) def should_alarm(current_boxes): history.append(current_boxes) fire_frames = 0 for boxes in history: if any(box[5] == 0 for box in boxes): # 类别0对应火焰 fire_frames += 1 return fire_frames >= 3

叠加这个逻辑后,夜晚灯光误报明显减少,因为灯箱和车尾灯虽然颜色像火焰,但它们在画面里是静态的。这一条经验对于所有火焰检测项目都有参考价值。

第三步,把误报截图收集起来,作为背景图放回训练集做增量训练。具体做法是:新建一批不带标注文件的图片,加入数据集的images/train目录中。图片里没有目标,对应labels/train目录也不需要标签文件,YOLOv5会把这些图当作负样本参与训练。通过这种方式,模型会逐渐把“红色灯箱”视为背景。重新训练后,误报从一天二三十次降到了每周一两次,效果立竿见影。

负样本的数量需要控制,我一般控制在正样本总数的20%到40%。加太多会让模型偏保守,导致真实火情的召回率下降。

5. 从Demo到落地:模型轻量化与工程化部署思路

5.1 导出ONNX,再用TensorRT加速

训练好的best.pt只能跑在YOLOv5的Python环境里,想要部署到生产环境或者边端设备,一般要先导出成ONNX格式:

python export.py --weights runs/train/exp/best.pt --img 640 --include onnx

得到.onnx文件后,可以转成TensorRT引擎,在NVIDIA显卡上获得大幅推理加速。实测下来,yolov5s用TensorRT的FP16精度推理,比PyTorch原生推理快2到4倍,在Jetson Orin这类边缘设备上可以跑出实时帧率。如果部署在无GPU的机器上,可以考虑ONNX Runtime配合INT8量化,但烟雾这类半透明目标对量化比较敏感,INT8精度下降会比较明显,建议先跑一遍本地验证集确认效果。

5.2 边缘设备和多路视频监控的注意点

部署到边缘设备时,模型选择要克制。树莓派这类CPU设备能跑到每秒几帧就不错了,所以要么用最小的yolov5n并把输入分辨率降到416,要么干脆放弃低端板子,选用带GPU的Jetson系列或者x86工控机加独立显卡。监控场景需要同时处理多路视频流时,我通常的做法是:一个推理进程管理一个GPU上下文,内部用线程池轮转处理多路摄像头,而不是为每路摄像头都单独加载一个模型,显存占用会小很多。

工程上还有几个容易被忽略的点。报警联动不要逐帧保存图片,否则一张火警卡几十秒就能把硬盘塞满。更好的设计是:检测到目标后,只保存触发报警前几秒到后几秒的视频片段,同时推送一条带截图的消息到值班平台。这需要在推理主循环外面维护一个环形缓冲队列。

模型版本管理同样重要。现场部署后,每过一段时间就会收集到新场景的误报和漏报样本。我习惯按照轮次建立独立数据集目录,比如datasets/fire_smoke_round2/,每轮训练都在上一次的数据基础之上增加新样本,训练完成后生成新best.pt,并保留上一个版本,方便回滚。不要在原数据集上覆盖式更新,这一点很关键,因为现场回传的样本质量参差,直接混进去可能把模型带偏。

最后分享一个我踩过多次坑之后的体会:做火焰烟雾检测,最大的精力投入不应该在调模型结构上,而是建负样本库。漏检可以通过加分辨率、加正样本逐步改善,误报却往往因为模型没见够现场的真实干扰物。每次落地新场景,我都让现场把至少一周的报警截图导出来,人工筛选后放进下一轮训练集当作背景图。这样迭代两三轮,误报基本就压下来了。这个思路比反复调置信度阈值有用得多。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 19:15:40

HTML系列教程:11_HTML 图像 <img> 标签零基础详解

<img> 用来在网页插入图片&#xff0c;image 的缩写。 <img> 是单标签&#xff0c;没有结束标签 </img>。 注意&#xff1a;img 标签写在 <body> 里面&#xff0c;不要写到 head。基础语法&#xff1a;<img src"图片地址" alt"图片描…

作者头像 李华
网站建设 2026/9/8 19:15:07

从面板到多标签页:SkillHub 0.2.0 交互重构与状态管理实践

老读者应该知道&#xff0c;SkillHub 这个项目我从 0.1.0 就开始在社区同步进展&#xff0c;它是一个面向开发者与创意工作者的本地技能工作台&#xff0c;把高频的小工具、模板片段、常用命令统一收拢到一个应用里&#xff0c;省得在不同软件之间来回横跳。这次 0.2.0 更新&am…

作者头像 李华
网站建设 2026/9/8 19:13:43

乐学平台数据结构考题精讲:约瑟夫问题、验证表、循环小数与BFS

简介&#xff1a;北理工大二数据结构课程乐学在线评测平台编程题的完整C实现合集&#xff0c;共29个cpp源码文件&#xff0c;压缩包大小仅25KB&#xff0c;覆盖线性表、栈与队列、树与二叉树、图、查找与排序等数据结构核心内容&#xff0c;适合正在修读该课程或准备期末机考的…

作者头像 李华