资讯动态

基于YOLOv8的火焰烟雾检测系统实现与部署全流程解析

发布时间:2026/8/27 9:55:12 来源:尧图企业网站定制
简介计算机视觉中的目标检测技术近年来发展迅速YOLO系列模型凭借精度与速度的平衡成为工业视觉落地的热门选择。传统火焰烟雾检测依赖颜色分割或帧差法在光照变化、目标尺度差异和复杂环境干扰下误报频发而基于深度学习的检测方案能够有效应对这些难题。本文从卷积神经网络的基本原理出发介绍YOLOv8的模型结构与训练逻辑并围绕火焰烟雾检测这一典型场景详细说明数据集构建、模型微调、超参数调优、推理部署及报警策略等工程实践要点。无论是安防监控、工业消防还是森林防火项目开发者都可以参考这套方法快速搭建一套可运行的检测系统同时结合连续帧确认、ONNX转换等技巧优化误报与性能。1. 项目概述为什么火焰烟雾检测离不开深度学习做视觉检测这些年我越来越觉得火焰烟雾检测是个典型的看着简单、做起来头疼的方向。传统的感烟感温传感器响应慢等它报警的时候往往已经烧了一段时间而普通摄像头方案如果只用颜色分割或帧差法又会遇到一个致命问题——阳光下红色的卡车、飘动的云朵、甚至焊接火花都能触发误报现场安保人员被溜到没脾气。正是这种痛点催生了基于深度学习的火焰烟雾检测系统。YOLOv8作为Ultralytics推出的目标检测模型在精度和速度之间取得了相当好的平衡模型体积小、部署方式灵活既能跑在服务器上做多路视频分析也能压缩后移植到嵌入式设备做边缘检测。这篇文章要分享的就是一套完整可落地的实现方案从数据集准备、模型训练、参数调优到系统代码组织和部署避坑直接把源码和预训练模型的使用逻辑讲透。这套东西适合谁如果你是做安防监控、工业消防、森林防火相关项目的开发者或者正在学习YOLOv8目标检测想找一个贴近实际业务而不是只跑官方coco数据集的案例那这篇文章能帮你省下不少自己踩坑的时间。我尽量把参数设置、代码结构和常见问题的处理思路都写清楚你照着搭一套能跑起来的火焰烟雾检测系统问题不大。2. 整体设计与方案选型为什么是YOLOv8而不是其他模型2.1 火焰烟雾检测的特殊难点先说清楚火焰和烟雾检测到底难在哪里这决定了方案选型的方向。第一是外观不确定性。火焰没有固定形状随风摆动、颜色从内焰的蓝色到外焰的橙红色渐变亮度变化剧烈烟雾更是半透明、颜色从白到黑都有和背景融合后肉眼都很难分辨。传统算法很难用一套固定规则去覆盖这种情况。第二是环境干扰极其严重。室内场景有灯光、反光室外场景有阳光、云影、车灯这些在视觉特征上跟火焰初期状态有大量重叠。我做测试的时候发现单纯用颜色空间过滤一个穿红色衣服的人跑过镜头都能触发报警。第三是目标尺度差异大。火灾初期火焰可能只有几十个像素大小而蔓延后充满整个画面烟雾可以从一缕飘散变成笼罩大片区域。这种尺度跨度对目标检测模型的泛化能力要求很高。2.2 YOLOv8相比其他方案的优势对比一下几个可选的技术路线。经典图像处理方案比如YCbCr颜色空间分割、帧间差分法实现简单、CPU就能跑但误报率居高不下只能在受控场景用。双流CNN加RNN的时序方案精度还行但训练复杂度高、推理速度慢不适合实时监控。而YOLOv8这类单阶段检测器直接在特征图上回归目标框和类别概率速度上能跑到实时精度也够用。具体到YOLOv8它相比之前的YOLOv5有几个关键改进。骨干网络换成了C2f结构在不显著增加计算量的前提下提升了特征提取能力检测头做成解耦结构分类和回归分支各干各的收敛更快还引入了Anchor-Free机制省去了聚类生成先验框的步骤对新数据集的适配更顺滑。这些特性叠加起来意味着用YOLOv8训练一个自定义火焰烟雾检测模型比从零训练Fast R-CNN这类两阶段模型要省事得多。作为参考我在GTX 1660Ti 6GB显存的机器上实测过几个模型尺寸的推理性能输入分辨率同为640×640模型参数量推理耗时(ms)显存占用(训练)适用场景YOLOv8n3.2M约15约4GB嵌入式/低算力设备YOLOv8s11.2M约25约6GB普通GPU实时检测YOLOv8m25.9M约45约8GB服务器端高精度场景如果你手里的设备是比GTX 1660Ti更低功耗的嵌入式板卡优先用n模型做后续部署。如果精度不够再加s模型m模型在6GB显存下训练比较吃力需要调小batch size。2.3 数据与算力条件的现实约束选型还有一个现实考量数据从哪来、算力够不够。火焰烟雾的数据不像车牌识别那样有成熟的公开大数据集很多项目需要自己从视频里抽帧标注标注量一般也就在几千到几万张的量级。这种情况下用COCO预训练权重做迁移学习是必须的从零训练不但慢小数据集上也容易欠拟合。算力方面如果你只有CPU训练一个YOLOv8s模型可能要几天到几周基本不可行。我的建议是云GPU按小时租用训练本地GPU只做推理测试。一张T4或V100跑几百个epoch几十块到一百多块成本就能搞定比起自己买显卡划算得多。3. 环境配置与数据集准备3.1 环境搭建版本搭配和安装命令环境配置是整个项目里最容易出问题的地方很多朋友卡在这里。YOLOv8的安装比想象中简单核心依赖就是PyTorch和Ultralytics包但版本之间要搭配好。我这边验证过一套稳定组合你直接照着装就行# 创建虚拟环境Python版本建议3.9或3.10 conda create -n fire_detect python3.9 -y conda activate fire_detect # 安装PyTorch根据你的CUDA版本选择命令 # CUDA 11.8 pip install torch2.1.0 torchvision0.16.0 --index-url https://download.pytorch.org/whl/cu118 # 或者CUDA 12.1 # pip install torch2.1.0 torchvision0.16.0 --index-url https://download.pytorch.org/whl/cu121 # 安装Ultralytics pip install ultralytics # 验证安装 python -c from ultralytics import YOLO; print(YOLO(yolov8n.pt))有几个细节要提醒Python 3.12虽然新但部分依赖可能还没跟上稳妥起见用3.9或3.10。PyTorch版本不要追最新2.1.0这代比较稳定Ultralytics官方在2.x版本上测试最充分。如果你用的是GTX 1660Ti这类6GB显存的卡CUDA建议用11.8CUDA 12.x在新卡上优势明显老卡上反而看不出差别。安装完成后先把yolov8n.pt这个预训练权重下载好后面会用到。3.2 数据集来源与自建方案数据集是火焰烟雾检测的核心资产模型效果的上限基本由数据决定。公开数据集方面可以搜一下Fire Detection Dataset、Smoke Detection Dataset之类的关键词GitHub和Kaggle上都有一些整理好的数据集但质量和标注格式参差不齐。使用前务必检查标注是否完整、有无漏标错标否则后续训练就是浪费时间。更推荐的做法是自己采集和标注尤其是面向具体场景做定制化检测时。采集时注意几个原则覆盖不同光照白天、夜晚、黄昏、逆光每种都要有样本。覆盖不同距离近景大火、远景小火苗、烟雾初起状态。覆盖不同类型明火、阴燃、不同颜色的烟白烟、黑烟、灰烟。覆盖干扰源红车、路灯、晚霞、蒸汽、焊接火花这些负样本非常重要。标注工具我用的是LabelImg它输出Pascal VOC格式的XML文件再转成YOLO格式的txt。YOLO格式每一行是类别id 中心点x坐标 中心点y坐标 框宽度 框高度注意x、y、w、h都是归一化到0~1之间的数值。# XML转YOLO txt的片段 import xml.etree.ElementTree as ET def xml_to_yolo(xml_file, classes, output_file): tree ET.parse(xml_file) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) with open(output_file, w) as f: for obj in root.iter(object): cls_name obj.find(name).text cls_id classes.index(cls_name) box obj.find(bndbox) x1 float(box.find(xmin).text) y1 float(box.find(ymin).text) x2 float(box.find(xmax).text) y2 float(box.find(ymax).text) cx (x1 x2) / 2 / img_w cy (y1 y2) / 2 / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h f.write(f{cls_id} {cx} {cy} {w} {h}\n)数据集准备好后在项目根目录按YOLO格式组织目录结构dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/训练集、验证集、测试集按7:2:1或8:1:1划分划分时注意同一条视频的帧尽量放在同一个集合里避免数据泄露导致验证指标虚高。3.3 数据增强策略其实官方已经内置了数据增强是火焰烟雾检测的关键环节但好消息是Ultralytics在训练时默认开启了Mosaic增强、随机仿射变换、HSV扰动等策略我们不需要写额外的增强代码只要学会配置参数就行。重点说两个对火焰烟雾特别有用的参数hsv_h、hsv_s、hsv_v这三个参数控制色调、饱和度、明度的随机扰动。火焰在不同温度下颜色差异很大轻微扰动可以帮助模型学到更鲁棒的颜色特征。默认值0.015、0.7、0.4在大多数场景够用如果发现模型对颜色过于敏感可以把hsv_s和hsv_v适当调大。flipud上下翻转增强。这个参数对火焰检测要慎用因为火焰物理上总是向上燃烧的长年累月的监控画面没有倒着的火。如果开了flipud模型可能学到方向无关的火焰特征反而降低了判别力。建议设置成0.0。另外提一下Mosaic增强它把4张图拼成一张图训练对小目标检测特别有帮助。但Mosaic会改变目标原有的尺度分布如果训练后期发现验证集上mAP波动大可以在最后几十个epoch把mosaic关掉让模型在真实分布上收敛一下。Ultralytics支持通过close_mosaic参数控制。4. 模型训练与参数调优全流程4.1 预训练模型选择与训练启动训练的自变量其实不多关键就几项选哪个基础模型、图像分辨率多大、训练多少轮、学习率多少。基础模型选择上我建议先用yolov8s.pt做基准GTX 1660Ti 6GB显存跑得动batch size调到8到16之间。如果显存不够有两个方案一是换yolov8n.pt二是保持s模型但把batch降到4同时开启梯度累积。图像分辨率我直接用640×640这是YOLOv8的默认值绝大多数场景够用。如果火焰目标都很小可以试试960分辨率但训练时间和显存占用会明显上升需要权衡。训练启动命令yolo detect train \ modelyolov8s.pt \ datafire_smoke.yaml \ epochs200 \ imgsz640 \ batch8 \ lr00.01 \ patience30 \ cacheTruedata参数指向一个YAML文件内容很简单path: /path/to/dataset train: images/train val: images/val test: images/test nc: 2 names: [fire, smoke]关于epochs200是起步值重点看patience早停机制——如果连续30个epoch验证集mAP没有提升训练会自动停止避免浪费时间。实际训练中火焰烟雾数据集的mAP通常在100到150个epoch左右趋于稳定后面继续训练提升有限。4.2 训练过程监控怎么判断模型在正常学习训练启动后不要干等着。Ultralytics会在runs/detect/train/目录下实时更新训练信息重点看这几个文件results.png训练曲线汇总图包含box_loss、cls_loss、dfl_loss、mAP50、mAP50-95等曲线。随着训练推进loss应该逐步下降然后趋于平稳mAP逐步上升最后收敛。如果loss出现反弹或者mAP剧烈波动说明学习率设置或数据有问题。confusion_matrix.png混淆矩阵能直观看到哪些类别互相混淆。火焰和烟雾互检率如果特别高考虑是否标注边界不清晰。val_batch*.jpg验证集上模型的预测效果图能直观看到漏检和误检的情况。这个我会定期翻一翻比单看数值指标更有感觉。这里有个小技巧如果训练过程中断了不用担心Ultralytics会自动保存last.pt作为断点可以用resumeTrue参数接着训练yolo detect train resumeTrue4.3 超参数调整从默认参数到针对性优化默认参数在大多数数据集上表现不差但要达到更好的效果有几处针对性调整值得做。学习率是第一个要关注的。lr0默认0.01如果损失曲线前期下降太猛后期震荡可以降一档到0.005。如果你用yolov8s在自定义小数据集上训练0.01经常会让模型前期过拟合把lr0降到0.005后收敛更平稳。第二个是类别不平衡问题。火焰和烟雾在实际场景里出现频率往往差异很大如果烟雾样本远超火焰样本模型会偏向检测烟雾。解决办法两个一是收集更多火焰数据二是在损失函数层面调权重。Ultralytics支持在YAML里配置每个类别的权重但实际操作中我优先加数据因为类别权重调过头容易让模型在少样本类别上过拟合。第三个是置信度阈值和NMS相关的推理参数这个在训练阶段影响不大但到预测阶段就很重要了。官网的默认置信度阈值是0.25火焰烟雾检测建议调高到0.35到0.5之间。原因是火焰烟雾误检代价高宁可漏报通过提高灵敏度弥补也不愿误报频繁打扰监控中心。当然这个要根据实际场景权衡。4.4 模型评估单卡推理测试训练完成后用验证集或测试集做一次推理验证yolo detect predict \ modelruns/detect/train/weights/best.pt \ sourcetest_images/ \ conf0.4 \ iou0.5 \ saveTrue跑完看一眼带预测框的图片重点关注是否出现同一目标被重复框选的情况NMS阈值可能太小。是否有把背景当火焰的错误框置信度阈值可能太低或需要增加负样本。小目标的检测情况如何初期小火是否漏检严重。如果整体效果满意就把best.pt保存好后面做系统集成时的核心模型就是它了。5. 检测系统实现与代码拆解5.1 系统整体流程与报警逻辑设计模型训练完成只是第一步一套可用的火焰烟雾检测系统还需要工程化封装。我的系统结构是视频流输入 → 帧采样 → 模型推理 → 后处理 → 输出结果与报警。这里重点说一下报警逻辑这是实际落地过程中很多人忽略的地方。如果每一帧检测到火焰就报警误报率会非常高因为检测模型偶尔会有单帧误检。我的做法是引入连续帧确认机制class FireSmokeDetector: def __init__(self, model_path, conf_threshold0.4, frame_limit3): self.model YOLO(model_path) self.conf_threshold conf_threshold self.frame_limit frame_limit # 连续判定帧数 self.detect_count 0 self.alarm False def process_frame(self, frame): results self.model(frame, confself.conf_threshold, verboseFalse) has_fire False for result in results: for box in result.boxes: class_id int(box.cls[0]) if class_id in [0, 1]: # 0:fire, 1:smoke has_fire True if has_fire: self.detect_count 1 else: self.detect_count 0 if self.detect_count self.frame_limit: self.alarm True else: self.alarm False return self.alarm, results在这个逻辑里连续3帧都检测到火焰或烟雾才会触发报警大幅降低单帧误检的影响。你还可以加入消失帧数机制——比如连续10帧没有检测到目标才解除报警避免火焰在视频中闪烁导致报警信息反复触发。5.2 核心代码结构一个可运行的检测Demo下面这个demo可以从摄像头或视频文件读取画面实时检测并绘制结果import cv2 from ultralytics import YOLO def run_detection(video_source0, model_pathbest.pt): model YOLO(model_path) cap cv2.VideoCapture(video_source) # 设置分辨率降低分辨率可以提高FPS cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) detector FireSmokeDetector(model_path) while cap.isOpened(): ret, frame cap.read() if not ret: break alarm, results detector.process_frame(frame) # 绘制检测框 annotated_frame results[0].plot() if results else frame # 在画面左上角标出报警状态 status_text ALARM if alarm else NORMAL color (0, 0, 255) if alarm else (0, 255, 0) cv2.putText(annotated_frame, status_text, (30, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.2, color, 3) cv2.imshow(Fire Smoke Detection, annotated_frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows() if __name__ __main__: run_detection(video_sourcetest_video.mp4, model_pathbest.pt)这段代码已经可以跑通完整的检测流程。实际生产环境中你还要考虑多线程视频读取线程和模型推理线程分离避免IO阻塞导致画面卡顿。5.3 模型部署从PyTorch到ONNX/TensorRT模型训练好后下一步是部署到实际环境。PyTorch格式的.pt文件适合做推理验证但不适合直接部署到生产环境或嵌入式设备原因是推理效率低、依赖PyTorch环境、无法利用特定硬件加速。最常见的转换路径是导出ONNX再做后续转换yolo export modelbest.pt formatonnx imgsz640ONNX格式的好处是跨平台、跨语言的通用性。在服务器上用ONNX Runtime推理就够在嵌入式设备上可以先转ONNX再接TensorRT或NCNN。我实际测试过用TensorRT FP16精度在GTX 1660Ti上推理YOLOv8s模型速度可以从25ms提升到15ms左右提升还是明显的。如果你要部署到嵌入式设备比如Jetson Nano这类算力有限的设备建议用yolov8n模型做TensorRT INT8量化。INT8量化后模型体积缩小约4倍推理速度可能提升3倍左右但精度会有所下降。实际操作中要用校准集跑一遍量化看看mAP下降幅度是否在可接受范围内。5.4 界面与可视化方案有朋友会问需不需要做界面。如果只是开发调试阶段OpenCV的窗口足够用。但如果是给用户交付的项目做一个简单的Web界面会专业很多。最省力的方式是Ultralytics结合Streamlit做一个Web演示页面几十行代码就能实现视频上传、检测结果展示的功能import streamlit as st import tempfile from ultralytics import YOLO st.set_page_config(page_title火焰烟雾检测系统) st.title(火焰烟雾检测系统) model_path best.pt model YOLO(model_path) uploaded_file st.file_uploader(上传视频, type[mp4, avi, mov]) if uploaded_file: with tempfile.NamedTemporaryFile(deleteFalse, suffix.mp4) as tmp: tmp.write(uploaded_file.read()) tmp_path tmp.name st.video(tmp_path) if st.button(开始检测): result_video model.predict(sourcetmp_path, saveTrue, conf0.4) st.success(检测完成)这个方案适合演示和小型工具场景。生产级系统一般会用Flask或FastAPI做后端服务配合前端页面或接入现有的监控平台这部分根据具体项目需求定制就好。6. 常见问题与排查技巧实录6.1 训练过程中损失不降或NaN这是最高频的问题之一。先检查数据集标注文件用代码脚本扫描txt文件看看有没有坐标值超出0~1范围、框宽高为0、类别编号超出nc范围这些情况。这类脏数据会让损失函数直接爆炸。第二个检查点是学习率。如果lr0太高损失会震荡甚至发散。解决办法是把lr0降到0.001看看前几十个epoch是否恢复正常。第三个检查点是模型权重文件是否与模型结构匹配。如果你改了nc数量但误用了没改头的预训练模型训练会报错或损失异常。用官方yolov8s.pt作为起点它会自动适配你的类别数量。6.2 验收集上误检严重误检率高的原因很可能是数据覆盖不足。火焰烟雾的外观特征受环境和天气影响极大如果训练集里全是晴天室内场景模型到了夜晚或雨雾天就抓瞎。解决办法是持续补充各种环境下的样本尤其是负样本——那些长得像火焰但不是火焰的东西。另一个常见问题是置信度阈值太低。不要用默认的0.25建议调到0.4以上。如果你已经调高了阈值还是误检严重可以考虑用数据集增强模拟更多光线条件或者在推理时对检测结果做时间平滑滤波这个我在前面的连续帧确认里讲过了效果非常好。6.3 漏检小目标火焰初期火苗往往只有一个很小的区域YOLOv8在640×640分辨率下对小目标检测效果有限。几个可行的方案把输入分辨率从640提高到960或1280小目标包含的像素更多但推理耗时明显增加。用SAHI切片推理把原图切块后分别推理再合并结果对超大图和极小目标效果显著。针对小目标补充训练数据让火焰小目标的样本在数据集中占足够比例。注意每种方案都有代价提高分辨率会增加GPU负载切片推理会增加代码复杂度。在资源有限的项目里先算清楚收益与开销再动手。6.4 CPU上推理太慢如果你在无GPU的机器上做推理几个优化点用yolov8n模型比s模型快一倍以上。导出ONNX格式用ONNX Runtime的CPU执行器推理比直接用PyTorch快不少。降低输入分辨率从640降到416或320。开启torch.compile或ONNX Runtime的Intel CPU优化OpenVINO EP。实测在普通i5处理器上用yolov8n ONNX模型跑320分辨率单帧推理可以控制在100ms以内基本能满足摄像头每秒10帧的需求。6.5 训练和推理常见问题速查表问题现象可能原因解决思路训练loss为NaN学习率过高、标注数据异常降低lr0检查标注坐标是否越界训练早停但mAP很低数据集太小或归一化不一致丰富训练数据检查增强参数配置误检率很高置信度阈值低、干扰样本不足调高conf阈值补充负样本检测不到远处小火分辨率不足、小目标样本太少提高imgsz补充小尺度目标数据CPU推理卡顿模型过大、分辨率过高换yolov8n导出ONNX降低imgsz模型导出ONNX失败环境依赖冲突升级ultralytics到最新版检查onnx与onnxruntime版本7. 项目扩展与后续优化建议完成一套能跑的火焰烟雾检测系统之后如果你还有余力有几种方向可以做深。第一种是烟雾检测的时序建模。当前方案是单帧检测没有利用视频帧之间的时序信息。火焰开始燃烧时往往伴随闪烁特性烟雾传播有运动规律引入时序信息可以进一步降低误报率。做法是在检测结果后接一个LSTM或Transformer序列模型输入连续时刻的检测框信息输出是否触发报警。第二种是多光谱融合。普通RGB摄像头在浓烟环境里会失效可以接入红外热成像摄像头做双路融合。火焰在红外图像里特征非常明显热成像和RGB的联合输入能大幅提升检测鲁棒性。这个方向在森林防火项目中尤其有价值。第三种是损失函数改进。如果数据集类别不平衡严重或者你更关注召回率而非精确率可以尝试使用Wise-IoU或Focaler-IoU这类改进损失函数。Ultralytics框架里可以通过自定义loss模块来实现虽然改动有一定工作量但对特定场景非常有效。第四种是部署端的轻量化剪枝。如果目标设备算力很紧张可以对模型做通道剪枝或知识蒸馏用一个较大的教师模型训练一个小学生模型。这些都需要额外的工具支持不是开箱即用的功能但对有量产需求的项目来说是值得投入的。我在实际做这套系统的时候最大的体会是模型训练只占了整个项目三成的工作量真正的难点在数据采集、场景适配和报警策略的打磨上。你花一周时间把训练流程跑通但可能要花一个月才能把误报率降到客户能接受的水平。所以一开始不要追求模型花哨先把数据基础打扎实把推理链路和报警逻辑做干净再逐步迭代优化。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价