尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

基于YOLOv8+pyqt5的火焰烟雾检测系统:从模型训练到界面部署全流程拆解(含TaoToken配置)

基于YOLOv8+pyqt5的火焰烟雾检测系统:从模型训练到界面部署全流程拆解(含TaoToken配置) 1. 火焰烟雾检测系统落地YOLOv8 训练到 pyqt5 桌面端全链路拆解做火焰烟雾检测这个题目很多人卡住的地方其实不是模型本身而是训练完的权重怎么变成一个能点开就用的窗口程序。我见过太多同学best.pt躺在 runs 目录里报告写了一半界面却还停在 PyQt5 的空白窗体上。这篇就把 YOLOv8 火焰烟雾检测从数据集标注、训练参数、推理封装到 pyqt5 界面部署整条链路拆开讲顺带把模型服务调用的统一 Key/API 通道配置也带上方便你后面接在线模型做对比演示。火焰烟雾检测本质上是一个二分类或多分类目标检测任务输入是一张图片或一帧视频输出是火焰、烟雾两类目标的边界框和置信度。它适合谁做毕业设计、课程设计、安防类小项目的同学以及想快速验证一个检测 demo 的开发者。你不需要从零写网络结构YOLOv8 已经把 backbone、neck、head 都封装好了你要做的是把数据喂对、把参数调稳、把界面接上。整条链路我建议按这个顺序推进先明确检测类别和标注规范再准备数据集目录结构然后跑训练拿到权重接着写一个独立的推理脚本验证效果最后把这套推理逻辑塞进 pyqt5 的界面线程里。很多人顺序反了先写界面结果模型一换类别界面里的标签、颜色、置信度阈值全要重改。先把推理层和界面层解耦后面替换模型只改一个配置文件。下面每个环节我都会给出可直接复制的代码和参数包括数据集 yaml、训练命令、推理封装类、pyqt5 主窗口骨架以及通过统一 API 通道调用模型服务的配置片段。你照着跑基本能在一个下午把 demo 跑通。2. TaoToken 前置准备统一 Key 与 API 通道配置在讲训练之前先把这个统一通道说清楚因为后面推理脚本里如果要接在线模型做对比或者你想用大模型辅助生成标注描述、写报告提纲都会用到它。TaoToken 提供的是一个统一的 API 入口你只需要一个 Key就能通过兼容 OpenAI 风格的接口访问多种模型服务不用为每个模型单独申请账号、记不同的 Base URL。它的核心价值在于统一两个字Base URL 固定Key 固定模型 ID 按需切换。对于火焰烟雾检测这个场景你可以用它做几件事——比如让模型帮你把标注规范整理成文档、根据检测结果生成告警描述、或者在你调试 pyqt5 界面时帮你解释报错。这些都不影响本地 YOLOv8 的训练和推理属于辅助链路。配置方式很简单你需要在环境变量或配置文件里写入三个东西API Key、Base URL、Model ID。Base URL 用https://taotoken.net/api注意这个地址不带任何查询参数。Key 在控制台的 API Keys 页面生成生成后复制保存页面上只显示一次。如果你用的是 Claude Code 这类编码工具或者 Cline、Codex 这类支持自定义 provider 的客户端配置逻辑是一样的找到设置里的 Base URL 和 API Key 字段填入上面的值Model ID 填你实际要用的模型标识。有些客户端会要求你写auth.json或settings.json格式大同小异核心就是这三个字段。我建议你先把 Key 配好用一个最简单的 curl 请求验证通道是否通再去折腾训练。验证命令后面第 4 节会给。这里先记住Key 不要硬编码在 pyqt5 的界面代码里放到单独的配置文件或环境变量避免打包 exe 时泄露。3. 可复制配置数据集 yaml、训练参数与推理封装这一节是全文的核心所有配置都可以直接复制。先说数据集。火焰烟雾检测的数据集一般包含 fire 和 smoke 两类图片数量从几千到两万张不等。目录结构建议按 YOLO 标准来dataset/ images/ train/ val/ labels/ train/ val/标注用 labelImg 或 Roboflow 导出 YOLO 格式每张图对应一个 txt每行是class_id x_center y_center width height坐标都归一化到 0-1。类别顺序一定要和 yaml 里的 names 对应fire 是 0smoke 是 1别搞反否则训练出来框是对的但标签全错。数据集配置文件fire_smoke.yamlpath: ./dataset train: images/train val: images/val names: 0: fire 1: smoke训练命令用 ultralytics 的 CLI参数我调过几轮这套在 2 万张量级的数据上比较稳yolo detect train \ modelyolov8n.pt \ datafire_smoke.yaml \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ device0 \ projectruns/fire_smoke \ nameexp1如果你显存不够把 batch 降到 8 或 4imgsz 降到 416。patience20表示 20 轮没提升就早停省时间。训练完权重在runs/fire_smoke/exp1/weights/best.pt。推理封装我写成一个独立类方便 pyqt5 调用from ultralytics import YOLO import cv2 class FireSmokeDetector: def __init__(self, weight_path, conf0.4, iou0.45): self.model YOLO(weight_path) self.conf conf self.iou iou self.names self.model.names def detect(self, frame): results self.model.predict( sourceframe, confself.conf, iouself.iou, verboseFalse ) boxes [] for r in results: for box in r.boxes: x1, y1, x2, y2 box.xyxy[0].tolist() cls_id int(box.cls[0]) conf float(box.conf[0]) boxes.append({ label: self.names[cls_id], conf: conf, bbox: [int(x1), int(y1), int(x2), int(y2)] }) return boxes这个类只依赖 ultralytics 和 opencv不碰界面后面换模型只改weight_path。如果你要接在线模型服务做对比配置文件config.json这样写{ api_base: https://taotoken.net/api, api_key: 你的Key, model_id: 你的模型ID }读取时用json.load别写死在代码里。这样本地 YOLOv8 和在线服务可以并存界面里加个下拉框切换就行。4. 验证请求与成功结果从命令行到界面出框配置写完先别急着开界面用命令行验证两件事本地模型能不能出框在线通道能不能通。本地推理验证yolo detect predict \ modelruns/fire_smoke/exp1/weights/best.pt \ sourcetest.jpg \ conf0.4 \ saveTrue跑完在runs/detect/predict下会有一张画了框的图。如果火焰和烟雾都框出来了说明权重没问题。如果只框出一种检查标注里是不是某一类样本太少或者类别 id 写反了。在线通道验证用 curlcurl https://taotoken.net/api/v1/models \ -H Authorization: Bearer 你的Key返回一个模型列表 JSON 就说明通道通了。如果返回 401说明 Key 错了或没带Bearer前缀。这一步过了后面在 pyqt5 里调用才有意义。pyqt5 界面骨架核心是把推理放到子线程避免界面卡死import sys import cv2 from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QWidget, QFileDialog from PyQt5.QtGui import QImage, QPixmap from PyQt5.QtCore import QThread, pyqtSignal from detector import FireSmokeDetector class DetectThread(QThread): finished pyqtSignal(object, object) def __init__(self, detector, frame): super().__init__() self.detector detector self.frame frame def run(self): boxes self.detector.detect(self.frame) self.finished.emit(self.frame, boxes) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.detector FireSmokeDetector(runs/fire_smoke/exp1/weights/best.pt) self.setWindowTitle(火焰烟雾检测系统) self.label QLabel(请选择图片) self.btn QPushButton(打开图片) self.btn.clicked.connect(self.open_image) layout QVBoxLayout() layout.addWidget(self.label) layout.addWidget(self.btn) container QWidget() container.setLayout(layout) self.setCentralWidget(container) def open_image(self): path, _ QFileDialog.getOpenFileName(self, 选择图片, , Images (*.jpg *.png)) if not path: return frame cv2.imread(path) self.thread DetectThread(self.detector, frame) self.thread.finished.connect(self.show_result) self.thread.start() def show_result(self, frame, boxes): for b in boxes: x1, y1, x2, y2 b[bbox] color (0, 0, 255) if b[label] fire else (255, 0, 0) cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2) cv2.putText(frame, f{b[label]} {b[conf]:.2f}, (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) rgb cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, ch rgb.shape qimg QImage(rgb.data, w, h, ch * w, QImage.Format_RGB888) self.label.setPixmap(QPixmap.fromImage(qimg).scaled(self.label.width(), self.label.height())) if __name__ __main__: app QApplication(sys.argv) win MainWindow() win.show() sys.exit(app.exec_())跑起来点打开图片选一张有火焰的图界面上应该能看到红框和蓝框。这就是最小可用的检测演示。视频检测把cv2.imread换成cv2.VideoCapture在循环里调detect即可注意每帧都开子线程会爆改成定时器或单线程循环。5. 常见报错排查401、local proxy failed、reading choices、OAuth这一节列几个真实会撞上的报错对照着查。401 Unauthorized出现在调用在线通道时。原因通常是 Key 没带、Key 复制时多了空格、或者请求头写成了Authorization: 你的Key少了Bearer。检查配置文件里的api_key字段重新生成一个 Key 再试。注意 Base URL 用https://taotoken.net/api不要在后面加/v1之外的路径。local proxy failed这个报错一般出现在客户端工具里提示本地代理连接失败。先确认你的网络环境能正常访问外网再检查客户端设置里的 Base URL 是否填对。如果你在 settings.json 或 auth.json 里配了自定义地址确认格式是完整的https://taotoken.net/api不要漏掉协议头。这个报错和模型本身无关纯粹是通道配置问题。reading choices 相关报错通常出现在解析返回结果时比如KeyError: choices或list index out of range。原因是返回的 JSON 结构和你预期的不一样可能是请求失败返回了错误信息但你直接去取choices。加一层判断resp requests.post(url, headersheaders, jsonpayload) data resp.json() if choices not in data: print(返回异常:, data) else: content data[choices][0][message][content]OAuth 相关报错如果你用的客户端要求 OAuth 登录但你想用 API Key 方式需要在设置里切换到 API Key 模式。有些工具默认走 OAuth配置项藏在高级设置里。找到 provider 设置把认证方式改成 API Key填入你的 Key 和 Base URL。模型加载报错No module named ultralyticspip 装一下注意 Python 版本别太低3.8 以上。pip install ultralytics。pyqt5 界面卡死推理没放子线程。上面代码里用了 QThread如果你自己写的时候直接在按钮回调里调detect界面就会假死。记住任何耗时超过 100ms 的操作都丢到子线程。检测框位置偏移检查标注时的坐标是否归一化以及推理时 imgsz 是否和训练一致。训练用 640推理也用 640别一个 640 一个 1280。6. 从演示到交付把检测系统跑成可展示的完整项目到这一步你已经有了训练好的权重、能出框的推理类、能点开的 pyqt5 界面。接下来是把它整理成能交付的形态。毕业设计或课程设计通常要求有源码、有报告、有演示。源码部分建议按模块分目录detector.py放推理类ui.py放界面config.json放配置weights/放权重dataset/放数据。报告里的实验部分把训练时的 loss 曲线、mAP 指标、混淆矩阵截图放进去这些 ultralytics 训练完会自动生成在 runs 目录里。如果你想让演示更完整可以在界面里加一个在线模型对比按钮点击后把当前图片发给统一通道的模型服务让它生成一段检测描述和本地 YOLOv8 的结果并排显示。这样既展示了本地检测能力也展示了模型服务调用能力。配置就用第 3 节那个config.json读取后发请求即可。打包成 exe 用 pyinstaller注意把权重文件和 config.json 一起打进去用--add-data参数。打包后第一次运行可能会慢因为要解压依赖。最后提醒一句火焰烟雾检测的误报率在实际场景里不低尤其是黄昏的光线和红色物体。演示时选几张特征明显的图效果会好很多。如果你要接摄像头做实时的把置信度阈值调到 0.5 以上减少闪烁框。整套流程跑通后替换成其他检测类别也很快改 yaml 里的 names、重新标注、重新训练界面代码一行不用动。
返回列表