ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

基于YOLOv8与PyQt5的吸烟检测识别系统开发实战

基于YOLOv8与PyQt5的吸烟检测识别系统开发实战 各位做视觉开发、深度学习落地或者桌面应用集成的朋友应该都有类似的体会模型训练出来只是第一步真正要交付给客户或业务方使用还得给模型套上一个能看得见、摸得着的“外壳”。如果你正在做安全监管、消防预警或室内违规行为检测相关的项目那么“吸烟检测”大概率是需求清单里绕不开的一项。这篇文章我打算围绕YOLOv8 PyQt5做一套完整的抽烟吸烟检测识别系统从数据集准备、模型训练、模型导出到 PyQt5 界面开发、摄像头实时推理、多线程防卡顿再到常见报错排查一次性讲清楚。代码我会尽量给全方便你直接复制、修改、跑通。新手可以照着做一遍理解整个视觉检测项目的完整链路有基础的开发者可以直接跳到第四节看核心代码和工程化细节。需要先说明的是本文不涉及任何环境代理相关配置只关注模型训练和桌面应用集成本身安全合规的内容也会在文末做一个提醒。1. 背景与核心概念1.1 什么是吸烟检测识别系统吸烟检测识别系统本质上是“目标检测Object Detection”在特定场景下的应用。它的任务是给定一张图片或一段视频流算法自动找出画面中是否存在“正在吸烟的人”并框出吸烟目标的位置。与我们熟悉的通用目标检测比如检测行人、车辆、猫狗不同吸烟检测有两个难点目标小。香烟、打火机在画面中占比很小尤其是监控摄像头距离较远时模型很容易漏检。语义歧义。手指夹着的白色细长物体、嘴边的白色物体与香烟有一定相似性如果不结合手部姿态、脸部区域、烟雾特征很容易误检。所以在实际项目中很多人会把“吸烟检测”拆分成多个子任务先做人脸检测、再做人手检测、然后再判断手部区域是否有香烟特征也可以用端到端的目标检测模型直接标注“smoking”这个类别。前者准确率高但流程复杂后者简单直接适合快速落地。本文采用第二种方案也就是用 YOLOv8 训练一个端到端的吸烟检测模型。1.2 为什么选择 YOLOv8YOLOYou Only Look Once系列是目前工业界应用最广的目标检测算法之一。它把目标检测当作回归问题一次前向推理就能同时输出目标类别和边界框位置所以速度非常快。YOLOv8 是 Ultralytics 公司在 2023 年初推出的版本相比之前的 YOLOv5主要改进点包括C2f 模块在 C3 模块基础上引入更多分支连接让梯度流动更丰富特征提取能力更强。Anchor-Free 检测头不再依赖预设的 anchor 框简化了后处理逻辑对小目标更友好。解耦检测头Decoupled Head分类分支和回归分支分开收敛更快精度更高。更丰富的模型规格YOLOv8n / YOLOv8s / YOLOv8m / YOLOv8l / YOLOv8x从轻量级到高精度全覆盖。对于吸烟检测这种小目标场景我一般建议先用 YOLOv8s 或 YOLOv8m 起步如果推理设备性能有限比如只有 CPU再考虑 YOLOv8n。本文示例默认使用 YOLOv8s。1.3 为什么用 PyQt5 做界面PyQt5 是 Qt5 应用框架的 Python 绑定常被用来开发 Windows / Linux 桌面软件。对于视觉检测项目PyQt5 的优势在于控件丰富按钮、标签、下拉框、表格、画布等都很成熟能快速搭出专业界面。信号槽机制界面交互点击按钮、选择文件和业务逻辑之间通过信号槽解耦代码结构清晰。与 OpenCV 配合方便OpenCV 读到的图像是numpy.ndarrayPyQt5 中可以很方便地转换成QImage/QPixmap显示在界面上。打包部署成熟配合 PyInstaller 可以打成 exe方便交付给没有 Python 环境的客户。简单来说YOLOv8 负责“看得见”PyQt5 负责“让人看得见”。模型负责输出坐标和类别界面负责把结果呈现给用户并提供交互入口。1.4 应用场景工厂车间、仓库、加油站等禁烟区域的安全监控网吧、餐厅、候车室等公共场所的违规吸烟提醒家庭、宿舍场景的吸烟行为监测森林防火中的人员吸烟行为识别配合红外摄像头2. 环境准备与版本说明2.1 运行环境本文以 Windows 10/11 为例代码同样适用于 Linux。硬件方面建议优先使用 NVIDIA 显卡GTX 1660Ti 及以上级别都能跑 YOLOv8s 训练显存 6GB 以上比较从容。如果没有独立显卡可以先用 CPU 训练小型模型做功能验证速度会慢很多但不影响理解流程。版本方面下面的组合是我目前稳定使用的但版本更新较快你需要根据实际情况调整依赖库参考版本说明Python3.8 - 3.11建议 3.9 或 3.10兼容性最好ultralytics8.x 最新稳定版已集成 YOLOv8PyQt55.15.x稳定版本opencv-python4.8 以上图像处理torch2.x cu118 / cu121根据 CUDA 版本选择torchvision与 torch 对应不要单独乱装numpy1.24.x左右避免与 torch 冲突2.2 安装依赖建议新建一个虚拟环境避免把系统 Python 环境搞乱。# 创建虚拟环境 conda create -n smoke_detect python3.9 -y conda activate smoke_detect # 安装 PyTorch以 CUDA 11.8 为例CPU 版本请去 PyTorch 官网选对应命令 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 安装 YOLOv8 及视觉相关库 pip install ultralytics opencv-python # 安装 PyQt5 pip install pyqt5 pyqt5-tools如果你在国内网络环境下安装速度慢可以临时切换为国内镜像源pip install ultralytics opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple2.3 验证安装在 Python 交互环境或脚本中执行import torch import ultralytics import cv2 from PyQt5.QtWidgets import QApplication print(torch:, torch.__version__) print(cuda available:, torch.cuda.is_available()) print(ultralytics:, ultralytics.__version__) print(opencv:, cv2.__version__)如果torch.cuda.is_available()返回False说明 PyTorch 没有装到 GPU 版本或者 CUDA 驱动不对。后面第三节会单独讲怎么排查。3. 核心原理拆解YOLOv8 网络与 PyQt5 架构3.1 YOLOv8 网络结构速览YOLOv8 的整体结构可以分成三部分Backbone骨干网络负责提取图像特征。YOLOv8s 使用的是改进版 CSPDarknet核心模块是 C2f。相比 YOLOv5 的 C3C2f 把输入特征图分成两支经过多个 Bottleneck 后再拼接最后经过卷积调整通道数。这样做的目的是增加梯度流的分支数量让浅层特征和深层特征融合得更好对小目标检测有帮助。Neck颈部网络负责多尺度特征融合。YOLOv8 使用 PAN-FPN 结构简单理解就是把 Backbone 输出的三个不同尺寸特征图大特征图保留细节适合检测小目标小特征图语义强适合检测大目标反复做上采样、下采样和横向拼接让每一层都具备多尺度语义信息。吸烟检测中香烟目标偏向小目标所以我们需要特别关注 P3 层也就是较大尺寸的特征图的输出是否被充分利用。Head检测头YOLOv8 采用 Anchor-Free 解耦头。每个检测位置直接预测“中心点是否为目标”和“边界框的四边距离”然后通过 NMS非极大值抑制过滤掉重叠框。由于没有 anchor 数量、尺寸这些超参数训练时对数据集的适应能力更强。如果你打开 Ultralytics 的源码会发现网络结构是在ultralytics/nn/modules/head.py中定义的但实际使用时我们通常不需要手动搭建网络直接调用 YOLO 类即可。3.2 训练流程与关键参数说明YOLOv8 训练最核心的代码只有几行from ultralytics import YOLO model YOLO(yolov8s.pt) # 加载预训练权重 model.train(datasmoke.yaml, epochs100, imgsz640, batch16)但这里有几个参数值得展开说明epochs完整遍历数据集的次数。抽烟检测数据集如果比较小几百张到两千张100 到 150 轮足够如果数据集很大可以适当减少。观察训练日志当验证集的 mAP 不再明显上涨时就可以提前停止。imgsz输入图片尺寸。默认 640如果香烟目标非常小可以尝试 960 甚至 1280但显存占用会成倍增加。batch批大小。训练时受显存限制YOLOv8s 640 输入 batch16大概需要 8GB 左右显存。如果显存不足优先把 batch 降到 8 或 4而不是直接换小模型。device指定训练设备例如device0表示第一张显卡devicecpu用 CPU。YOLOv8 会自动保存训练过程中的损失曲线、验证集检测结果、混淆矩阵等输出路径在runs/detect/train/目录下。3.3 PyQt5 界面架构与多线程必要性PyQt5 的界面开发遵循三个基本概念信号Signal与槽Slot控件发生事件如按钮点击时发出信号槽函数响应信号。比如button.clicked.connect(self.on_click)点击按钮后自动调用on_click方法。事件循环app.exec_()启动 Qt 事件循环程序在这里持续监听用户操作。线程模型PyQt5 中UI 更新只能在主线程进行。如果你的推理过程直接写在主线程一旦模型推理耗时较长界面就会“卡死”窗口无法拖动、按钮无法点击用户体验很差。所以对于摄像头实时检测和视频文件检测我们通常把“读取帧 模型推理”放到QThread子线程中完成然后通过信号把处理结果传回主线程更新界面。Danger不要在子线程中直接调用QLabel.setText()、QLabel.setPixmap()等 UI 更新操作会导致崩溃或显示异常。3.4 数据集准备工作训练一个端到端的吸烟检测模型最少需要几百张到两三千张标注图片。数据来源有两个方向公开数据集GitHub、Kaggle 上可以找到 SMOKE 相关的目标检测数据集比如“Smoke Detection Dataset”。有些数据集包含 bounding box 标注格式可能是 PASCAL VOCxml或 YOLOtxt。自行采集标注从监控视频中抽帧筛选出包含吸烟行为的图片使用 LabelImg 或 Label Studio 标注标注类别名统一为smoking。数据集的目录结构建议如下smoke_dataset/ ├── images/ │ ├── train/ # 训练集图片 │ └── val/ # 验证集图片 ├── labels/ │ ├── train/ # 对应的 yolo 格式 txt 标注 │ └── val/ └── smoke.yaml # 数据集配置文件其中smoke.yaml内容如下# 文件路径smoke_dataset/smoke.yaml path: D:/projects/smoke_dataset # 数据集根目录Windows 注意斜杠方向 train: images/train val: images/val nc: 1 # 类别数量 names: [smoking] # 类别名称YOLO 格式的标注 txt 每一行代表一个目标类别id 中心点x 中心点y 宽度 高度坐标值都做了归一化范围在 0 到 1 之间。例如0 0.512345 0.432101 0.123456 0.234567表示这幅图中有一个“smoking”目标中心点在图片的相对位置 (0.512, 0.432)宽高相对尺寸为 (0.123, 0.235)。4. 完整实战案例YOLOv8PyQt5 抽烟吸烟检测系统接下来进入到文章最核心的部分。我会先带你完成 YOLOv8 模型训练与导出再写一个完整的 PyQt5 可视化检测界面支持图片检测、视频文件检测和摄像头实时检测。4.1 创建项目结构先新建一个项目文件夹名字可以叫smoke_detector。目录结构如下smoke_detector/ ├── train.py # 训练脚本 ├── detect.py # PyQt5 可视化检测主程序 ├── smoke_dataset/ │ ├── images/ │ ├── labels/ │ └── smoke.yaml └── runs/ └── detect/ └── train/ # 训练输出模型 └── weights/ └── best.pt4.2 训练 YOLOv8 模型在train.py中写入# 文件路径smoke_detector/train.py from ultralytics import YOLO def main(): # 加载预训练权重基于 COCO 数据集预训练 model YOLO(yolov8s.pt) # 开始训练 model.train( datasmoke_dataset/smoke.yaml, epochs150, imgsz640, batch16, device0, workers4, patience30, # 30轮没有提升则提前停止 projectruns/detect, nametrain_smoke, exist_okTrue, ) if __name__ __main__: main()运行python train.py训练结束后在runs/detect/train_smoke/weights/下会生成两个文件best.pt验证集上效果最好的权重部署时优先使用这个last.pt最后一轮的权重适合断点续训你还可以在训练过程中打开runs/detect/train_smoke/val_batch0_pred.jpg这类图片直观查看模型在验证集上的检测效果。4.3 导出模型为 ONNX可选如果后续需要做 C 部署、RK3588 等边缘设备部署或者其他框架集成可以先把 PyTorch 权重导出为 ONNX 格式。from ultralytics import YOLO model YOLO(runs/detect/train_smoke/weights/best.pt) model.export(formatonnx, imgsz640, opset12)导出后在相同目录下会生成best.onnx。这里提醒一下ONNX 导出后建议用onnxruntime测试一遍输出形状确保与 PyTorch 模型的输出一致。不过本文的 PyQt5 系统直接使用.pt权重不需要导出。4.4 编写 PyQt5 检测界面下面给出一个完整可运行的detect.py功能包括选择图片文件在界面上显示检测结果选择视频文件逐帧检测并实时显示打开摄像头实时检测显示当前检测到的吸烟目标数量支持调整置信度阈值先导入依赖# 文件路径smoke_detector/detect.py import sys import cv2 import numpy as np from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QLabel, QPushButton, QVBoxLayout, QHBoxLayout, QFileDialog, QSlider, QSpinBox, QComboBox, QMessageBox) from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer from PyQt5.QtGui import QImage, QPixmap from ultralytics import YOLO4.4.1 推理线程类视频和摄像头检测需要单独开线程避免界面卡顿。定义如下class VideoThread(QThread): frame_signal pyqtSignal(np.ndarray, int) # 传递图像和检测数量 error_signal pyqtSignal(str) def __init__(self, model, source, conf_thres0.25): super().__init__() self.model model self.source source self.conf_thres conf_thres self.running True def run(self): cap cv2.VideoCapture(self.source) if not cap.isOpened(): self.error_signal.emit(无法打开视频或摄像头源: {}.format(self.source)) return while self.running: ret, frame cap.read() if not ret: break # 模型推理 results self.model.predict(sourceframe, confself.conf_thres, verboseFalse) # 在图像上绘制检测框 annotated results[0].plot() # 返回标注后的 BGR 图像 # 统计检测数量 count len(results[0].boxes) # 发送到主线程 self.frame_signal.emit(annotated, count) cap.release() def stop(self): self.running False这里有几个要点需要说明results[0].plot()会直接在原图上绘制检测框、类别名和置信度返回 BGR 格式的 numpy 数组。frame_signal携带了图像和当前帧的检测数量因为 PyQt 信号可以携带多个参数。线程通过running标志位控制循环退出关闭窗口或切换检测源时记得调用stop()。4.4.2 主窗口类接着定义主界面class SmokeDetectorWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(YOLOv8 PyQt5 抽烟吸烟检测识别系统) self.resize(960, 640) # 加载模型 try: self.model YOLO(runs/detect/train_smoke/weights/best.pt) except Exception as e: QMessageBox.critical(self, 模型加载失败, str(e)) sys.exit(1) self.video_thread None self.conf_thres 0.25 self.init_ui() def init_ui(self): # 中央控件 central_widget QWidget() self.setCentralWidget(central_widget) # 主布局左侧控制区 右侧显示区 main_layout QHBoxLayout(central_widget) # 左侧控制面板 control_panel QVBoxLayout() self.btn_image QPushButton(选择图片检测) self.btn_video QPushButton(选择视频检测) self.btn_camera QPushButton(打开摄像头) self.btn_stop QPushButton(停止) self.btn_stop.setEnabled(False) # 置信度设置 conf_label QLabel(置信度阈值) self.conf_slider QSlider(Qt.Horizontal) self.conf_slider.setRange(10, 90) self.conf_slider.setValue(25) self.conf_value QLabel(0.25) self.conf_slider.valueChanged.connect(self.on_conf_changed) control_panel.addWidget(self.btn_image) control_panel.addWidget(self.btn_video) control_panel.addWidget(self.btn_camera) control_panel.addWidget(self.btn_stop) control_panel.addWidget(conf_label) control_panel.addWidget(self.conf_slider) control_panel.addWidget(self.conf_value) control_panel.addStretch() # 右侧显示区 self.label_image QLabel(请选择图片、视频或打开摄像头) self.label_image.setAlignment(Qt.AlignCenter) self.label_image.setMinimumSize(800, 600) self.label_image.setStyleSheet(border: 1px solid #cccccc; background-color: #f8f8f8;) main_layout.addLayout(control_panel, 1) main_layout.addWidget(self.label_image, 4) # 顶部状态栏显示检测数量 self.statusBar().showMessage(就绪) # 绑定按钮事件 self.btn_image.clicked.connect(self.open_image) self.btn_video.clicked.connect(self.open_video) self.btn_camera.clicked.connect(self.open_camera) self.btn_stop.clicked.connect(self.stop_detection) def on_conf_changed(self, value): self.conf_thres value / 100.0 self.conf_value.setText({:.2f}.format(self.conf_thres))4.4.3 图片检测逻辑图片检测不需要多线程直接在按钮回调里处理即可def open_image(self): file_path, _ QFileDialog.getOpenFileName( self, 选择图片, , 图片文件 (*.jpg *.jpeg *.png *.bmp);;所有文件 (*) ) if not file_path: return # 停止视频/摄像头线程 self.stop_detection() image cv2.imread(file_path) if image is None: QMessageBox.warning(self, 提示, 图片读取失败: {}.format(file_path)) return results self.model.predict(sourceimage, confself.conf_thres, verboseFalse) annotated results[0].plot() count len(results[0].boxes) self.show_image(annotated) self.statusBar().showMessage(检测到吸烟目标数量: {}置信度阈值: {:.2f}.format(count, self.conf_thres)) def show_image(self, img_bgr): # BGR - RGB - QImage rgb_image cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB) h, w, ch rgb_image.shape bytes_per_line ch * w q_image QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format_RGB888) # 缩放显示保持长宽比 pixmap QPixmap.fromImage(q_image) pixmap pixmap.scaled(self.label_image.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.label_image.setPixmap(pixmap)4.4.4 视频和摄像头检测逻辑视频和摄像头都是使用VideoThread区别只是source的值def open_video(self): file_path, _ QFileDialog.getOpenFileName( self, 选择视频, , 视频文件 (*.mp4 *.avi *.mov *.mkv);;所有文件 (*) ) if not file_path: return self.start_video_thread(sourcefile_path) def open_camera(self): # 0 表示默认摄像头如果有多个摄像头可以修改索引 self.start_video_thread(source0) def start_video_thread(self, source): self.stop_detection() self.video_thread VideoThread(self.model, source, self.conf_thres) self.video_thread.frame_signal.connect(self.on_frame_received) self.video_thread.error_signal.connect(self.on_thread_error) self.video_thread.start() self.btn_stop.setEnabled(True) self.statusBar().showMessage(检测中...) def on_frame_received(self, frame, count): self.show_image(frame) self.statusBar().showMessage(实时吸烟检测中当前检测数量: {}.format(count)) def on_thread_error(self, msg): self.btn_stop.setEnabled(False) QMessageBox.warning(self, 错误, msg) def stop_detection(self): if self.video_thread is not None: self.video_thread.stop() self.video_thread.wait() self.video_thread None self.btn_stop.setEnabled(False)4.4.5 程序入口最后是主函数def main(): app QApplication(sys.argv) window SmokeDetectorWindow() window.show() sys.exit(app.exec_()) if __name__ __main__: main()4.5 运行与验证在项目根目录执行python detect.py预期效果点击“选择图片检测”选择一张包含吸烟行为的图片右侧区域显示带检测框的结果状态栏显示检测数量。点击“选择视频检测”选择一段监控视频视频画面逐帧显示检测框实时绘制窗口不卡顿。点击“打开摄像头”摄像头画面实时显示移动摄像头对准吸烟行为能实时框出目标。拖动“置信度阈值”滑块检测框的敏感度会变化阈值越高漏检越多误检越少。如果你在图片检测时看到结果说明整个流程已经跑通。5. 常见问题与排查思路以下是我在实际运行中遇到较多的问题按“现象 → 原因 → 解决方案”整理成表格方便你快速定位。问题现象常见原因解决思路训练时报错 CUDA out of memory显存不足降低 batch 到 4 或 2降低 imgsz 到 640 以下或换 YOLOv8n 模型torch.cuda.is_available() 返回 FalsePyTorch 装成了 CPU 版本或显卡驱动过旧使用nvidia-smi查看 CUDA 版本卸载后重装对应版本的 PyTorchPyQt5 窗口闪退或卡死推理放在主线程或子线程直接更新 UI把推理放到 QThread用信号槽传回主线程更新 UI无法打开视频或摄像头源摄像头被其他程序占用视频路径包含中文且 OpenCV 无法识别关闭其他摄像头占用程序路径尽量不要包含中文检测效果不好漏检多数据集太小、标注质量差、置信度阈值太高增加数据量检查标注框是否贴合目标适当降低置信度阈值检测框抖动明显阈值过低导致误检或模型未收敛提高置信度阈值训练更多 epoch或使用 NMS 参数调节PyQt5 界面显示图片颜色异常OpenCV 是 BGR 格式QLabel 显示需要 RGB使用cv2.cvtColor(img, cv2.COLOR_BGR2RGB)转换模型加载后推理速度很慢使用了 CPU 推理检查torch.cuda.is_available()确保模型在 GPU 上运行best.onnx导出后推理结果不一致导出时 opset 版本或动态轴设置问题使用 YOLO 官方model.export()默认参数或指定dynamicTrue验证再补充一个比较隐蔽的问题在 PyQt5 中使用 OpenCV 读取视频时如果视频文件路径包含中文字符在某些版本的 OpenCV 中会直接返回False。推荐的做法是先把文件复制到英文路径或者使用imdecode方式读取。import cv2 import numpy as np def read_image_unicode(path): data np.fromfile(path, dtypenp.uint8) img cv2.imdecode(data, cv2.IMREAD_COLOR) return img6. 最佳实践与工程建议6.1 数据集层面样本平衡负样本没有人吸烟、没有人出现的空场景也要加入训练集让模型知道“没有目标时不应该输出框”。一般建议正负样本比例在 3:1 到 5:1 之间。数据增强YOLOv8 默认开启了 mosaic、随机翻转、色彩扰动等增强策略对提升模型泛化能力很有帮助。如果训练数据较少可以手动增加亮度变化、模糊、雨雾等模拟监控场景。标注边界标注时不要只画香烟本体最好把“手持香烟的手部区域”和“嘴部区域”整体框进去目标上下文信息对检测更有利。对于正在点烟、拿着烟、抽烟、弹烟灰等不同姿态都要覆盖。6.2 训练与推理层面多尺度训练如果香烟是小目标可以在训练时开启multi_scaleTrue让模型接触多种输入尺寸增强尺度鲁棒性。置信度阈值选择在工厂场景中误报代价较高建议阈值设置在 0.35 到 0.5在消防预警场景中漏报代价更高建议阈值设置在 0.15 到 0.25。模型量化如果部署到边缘设备如 RK3588、Jetson Nano可以考虑将模型导出为 ONNX 并做 INT8 量化推理速度会有明显提升但精度会有一定损失需要在实际数据上验证。6.3 PyQt5 工程层面UI 更新统一走信号槽主线程之外的任何线程都不要直接操作控件。摄像头资源释放关闭窗口时一定要调用video_thread.stop()和cap.release()否则摄像头会被占用下次打开失败。使用 QTimer 做定时刷新如果你的业务需要轮询推理结果比如每 200ms 检测一次可以用QTimer配合单帧检测而不是开一个无限循环线程编写更容易退出更安全。打包 exe使用 PyInstaller 打包时需要把best.pt和依赖的动态库一起打进去建议用--add-data参数指定模型路径。打包前先在一个干净环境测试避免漏掉动态库导致 exe 在其他电脑上无法运行。6.4 合规提醒吸烟检测系统通常用于公共场所安全监管。在实际部署前请确认你的项目符合当地隐私合规要求包括但不限于在监控区域设置必要的提示标识视频数据存储和访问权限管理只保留业务必要的检测结果日志避免过度采集作为技术开发者我们有责任确保系统只在合法授权的场景下使用。7. 总结与学习路线到这里你已经完成了一套从训练到桌面落地的吸烟检测识别系统。回顾一下我们做了什么数据处理整理数据集目录编写 YOLOv8 训练配置模型训练使用 YOLOv8s 训练自己的吸烟检测权重并导出 best.pt界面开发用 PyQt5 搭建了图片 / 视频 / 摄像头三种检测入口多线程处理通过 QThread 避免界面卡顿信号槽传递检测结果异常排查整理了显存不足、路径中文、UI 卡死等常见问题的解决办法如果接下来你想继续深入可以从这几个方向选一个提升检测精度收集更多真实监控场景数据或加入注意力机制如 MHSA改进 YOLOv8 的 Neck专门强化小目标特征。换用 YOLO11Ultralytics 后续版本中也有 YOLO11和 YOLOv8 相比在网络结构上又做了调整你可以用同样的数据集对比一下两者精度和速度。部署到边缘设备把导出的 ONNX 模型部署到 RK3588 或其他嵌入式平台走摄像头 RTSP 拉流实现更低成本的节点部署。完善业务功能在 PyQt5 中加入检测记录查询、截图保存、告警弹窗、微信/短信通知等让系统更接近可交付的产品。这篇文章提供的代码是一个可运行的最小闭环实际项目中你还需要根据自己的数据、设备和业务需求去调整。建议先跑通整套流程再针对薄弱环节优化。如果你在复现过程中遇到文章里没覆盖到的问题欢迎在评论区描述你的报错信息、环境版本和操作步骤一起交流排查思路。也可以把文章收藏起来等用到的时候直接对照配置。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表