新闻详情

新闻详情

首页 / 资讯中心 / 详情

基于YOLOv8的储罐液位异常检测系统实现与部署

发布时间:2026/9/13 6:11:40来源:尧图网络
基于YOLOv8的储罐液位异常检测系统实现与部署
简介基于YOLOv8的石油储罐液位异常监测系统是一套面向计算机视觉方向学生的完整毕业设计资源涵盖源码、可视化界面、完整数据集与部署教程可直接运行适合毕设、课程设计或目标检测入门实践。资源共97个文件包含70个Python源码、12个pyc编译文件、5个XML配置、4个模型权重pt及txt说明与mp4演示视频等压缩包仅24.21MB已有45人学习下载。项目可输出混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果及标签分布图等评估图表便于答辩时直观展示模型性能整体按源码、模型、配置、说明分目录组织结构清晰适合快速复现与二次开发。1. 把储罐液位异常检测拆成视觉问题再落地石油储罐的液位监控过去主要靠雷达液位计和人工巡检但雷达液位计在大罐壁挂壁、泡沫干扰、油品介电常数突变时误差很大人工巡检更不可能 7×24 小时盯着。基于 YOLOv8 的视觉检测方案本质是把「液位是否异常」转成「目标检测模型能不能在画面里找到液位计刻度、浮子或油面轮廓」的问题。标题里这个系统把模型、数据集、界面和部署教程打包成可直接运行的工程对毕设或课设来说意味着不需要从零造轮子但要真正让它稳定工作还是得弄清楚检测策略、数据来源和部署环境这三件核心事。这套方案的适用者很明确有 Python 基础、做过分类或检测项目但没碰过工业场景的同学以及想快速验证 YOLOv8 在特定领域效果的技术人员。它解决的不只是「能不能检测」而是「异常判断怎么和现场监控联动」。下面按模型选型、数据构建、训练推理、可视化界面和部署调优的顺序把整套系统的实现路径梳理清楚。2. YOLOv8 模型基础结构、选型理由与数据准备2.1 YOLOv8 网络结构C2f 模块和 anchor-free 检测头YOLOv8 由 Ultralytics 团队在 2023 年发布它最核心的两个结构变化是骨干网络里的 C2f 模块和 anchor-free 的检测头。C2f 模块是 C3 模块的改进版。它的思路是把输入特征图拆成两条支路一条直接通过卷积另一条经过多个 Bottleneck 堆叠最后在输出维度上做 concat。相比 C3C2f 在相同计算量下让梯度反向传播时能覆盖更多短路径训练收敛更快。yolov8 模型结构中 c2f 出现的位置包括 backbone 的第 3、4、5 个 stage 和 neck 部分控制它的参数是channels和nBottleneck 重复次数。这部分结构可以对应到 yaml 文件里例如yolov8s.yaml中各层的args里的c2f关键字。检测头方面YOLOv8 弃用了 YOLOv5 的 anchor-based 方式改成直接预测目标中心点到四条边的距离也就是解耦头的 DFL 分支。# YOLOv8 detect head 简化示意PyTorch 风格 class Detect(nn.Module): def __init__(self, nc1, reg_max16): super().__init__() self.nc nc # 类别数 self.reg_max reg_max # DFL 的 bin 数量 self.cv2 nn.Conv2d(256, 4 * reg_max, 1) # 回归分支 self.cv3 nn.Conv2d(256, nc, 1) # 分类分支 def forward(self, x): # x: 来自 neck 的多尺度特征 box self.cv2(x) # 每个网格预测 4 组分布 cls self.cv3(x) # 每个网格预测类别得分 return box, cls代码里reg_max16意味着每个坐标用 16 个离散值做 softmax 加权求和而不是直接回归连续值这让模型对小目标的位置预测更稳。选型时要注意如果显存只有 6G 左右YOLOv8n 或 YOLOv8s 是更稳妥的起点YOLOv8m 在 640 分辨率下需要约 8G 显存毕设场景的数据量通常不大YOLOv8s 就是性价比最高的默认选择。对于储罐液位检测这个任务需要识别的目标通常是「液位计刻度」「浮子位置」或「罐体侧壁的液面线」这些目标在图像中尺寸变化不大anchor-free 设计减少了很多调参成本。尤其是液位计这种细长目标长宽比可能在 5:1 以上YOLOv8 的解耦头在分类回归上互不干扰对边界框回归的精度表现明显优于 YOLOv5。2.2 数据集构建不能只靠网上下载的现成资源标题写「完整数据集」实际项目中很难直接拿到石油储罐液位异常的公开数据poi 数据集、acne04 数据集那些和这个任务无关。常见做法有两种:一是找带有液位计的工业现场监控视频抽帧标注二是用合成数据补足。合成数据并不是偷懒反而能主动控制异常样本的比例。# 抽帧脚本从监控视频中按间隔抽帧保留 800x800 以内的分辨率 import cv2, os from pathlib import Path src_video raw/20240611.mp4 # 现场视频MP4 格式 frame_dir Path(frames) frame_dir.mkdir(exist_okTrue) cap cv2.VideoCapture(src_video) fps cap.get(cv2.CAP_PROP_FPS) / 3 # 每 3 秒取一帧 count 0 saved 0 while True: ret, frame cap.read() if not ret: break if int(count % fps) 0: frame cv2.resize(frame, (1280, 720)) # 统一尺寸 cv2.imwrite(fframes/{src_video.stem}_{saved:04d}.jpg, frame) saved 1 count 1 cap.release()代码里按 3 秒间隔抽帧一是减少相邻帧相似度过高导致的过拟合二是让训练/验证集划分更有意义。抽出的帧用 labelme 或 X-AnyLabeling 标注格式转成 YOLO 的 txt。关于数据集规模工业检测场景一般不建议堆数据量而是注重类别平衡。液位计的异常状态高液位、低液位、浮子卡滞各准备 200~300 张正常状态 800~1000 张总共 1500~2000 张就足够 YOLOv8s 收敛了。数据增强用 YOLOv8 内置的即可hsv_h0.015、hsv_s0.7、flipud0.5。需要注意储罐现场光照变化剧烈hsv_v默认的 0.4 可以适当提高否则早晚光线差异很容易造成漏检。3. 训练与推理实现环境配置、损失曲线与异常判定3.1 环境配置和训练命令不要卡在安装上yolov8 环境配置是检索最多的词很多报错集中在 CUDA 版本不匹配和 torch 安装失败。常见做法是先装 CPU 版跑通流程再装 GPU 版提速。# 推荐配置顺序Python 3.10 实测可行 conda create -n yolo8 python3.10 -y conda activate yolo8 pip install torch2.1.2 torchvision0.16.2 --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics8.2.0–index-url指定了 CUDA 11.8 的预编译 wheel避免 pip 自动拉到最新版导致 nvidia 驱动不兼容。Ultralytics 8.2.0 是 2024 年的稳定版本不建议直接追新有些版本把conf参数默认值改掉了同一套推理脚本在新旧版本上行为不一致。数据集目录结构放在datasets/tank_liquid/下datasets/tank_liquid/ ├── images/ │ ├── train/ 含约 1400 张 │ └── val/ 含约 400 张 ├── labels/ │ ├── train/ 与 images/train 同名 txt │ └── val/ └── data.yamldata.yaml 是关键配置train: datasets/tank_liquid/images/train val: datasets/tank_liquid/images/val nc: 2 names: [gauge, floating_ball] # 刻度盘和浮子训练命令用官方封装即可但建议把分辨率固定到 640 而不是 1280。储罐液位计在画面里通常只占一块区域不是全局小目标640 已经够用分辨率提升一倍训练时间增加三倍收益很小。yolo detect train \ modelyolov8s.pt \ datadatasets/tank_liquid/data.yaml \ imgsz640 \ epochs100 \ batch16 \ patience15 \ device0 \ projectoutput/tank_train \ nameexp1patience15是早停耐心值如果验证集 mAP 连续 15 轮没有提升就停止训练课设环境里一般 60~80 轮就能拟合没必要开满 100 轮。训练输出里重点看P精确率、R召回率和mAP50三项。液位异常监测本质上是稀有事件检测宁可把浮子框大一点也不要漏检所以召回率比精确率优先级高调参时可以把conf_thres降到 0.25 来换取高召回。3.2 yolov8 画损失函数曲线图判断模型是否真的收敛训练完不是看 mAP 就直接上线的要先看损失曲线判断模型有没有过拟合或欠拟合。Ultralytics 会在训练目录下生成results.png它是 yolov8 画损失函数曲线图最直接的方式。但很多时候项目改了模型结构比如在 head 里加了注意力机制官方绘图工具无法反映每个模块的梯度情况用自定义回调更实用。from ultralytics import YOLO import matplotlib.pyplot as plt import pandas as pd model YOLO(output/tank_train/exp1/weights/best.pt) metrics model.val() # 读取训练日志Ultralytics 自动保存 results.csv df pd.read_csv(output/tank_train/exp1/results.csv) plt.figure(figsize(10, 5)) plt.plot(df[epoch], df[train/box_loss], labelbox_loss) plt.plot(df[epoch], df[val/box_loss], labelval_box_loss) plt.xlabel(epoch) plt.ylabel(loss) plt.legend() plt.savefig(loss_curve.png, dpi200)判断标准是训练 loss 和验证 loss 同时下降并且各自收敛到平缓区间说明拟合正常如果验证 loss 在第 40 轮之后持续上升而训练 loss 还在下降说明过拟合需要加dropout0.1或者增加数据增强的hsv_h系数如果两个 loss 都没明显下降大概率是学习率初始值设置错了YOLOv8 默认lr00.01是适配 COCO 这种大数据集的对于只有一千多张的小数据集可以降到 0.005。3.3 推理脚本从图片检测到计算液位高度训练完成后进入部署推理环节核心是判断液位是否超出安全范围。这里给出一个关键思路不要只输出类别标签而是把检测框的坐标换算成液位的像素高度比例。import cv2 from ultralytics import YOLO model YOLO(output/tank_train/exp1/weights/best.pt) def get_liquid_level(frame): results model(frame, verboseFalse)[0] # 液位计检测框假设类别 0 是刻度盘 gauge_boxes [b for b in results.boxes if int(b.cls) 0] if len(gauge_boxes) 0: return None # 取面积最大的刻度盘作为主液位计 gauge max(gauge_boxes, keylambda b: (b.xyxy[0][2]-b.xyxy[0][0]) * (b.xyxy[0][3]-b.xyxy[0][1])) x1, y1, x2, y2 gauge.xyxy[0].tolist() # 异常点检测假设类别 1 是浮子 ball [b for b in results.boxes if int(b.cls) 1] if len(ball) 0: return normal # 浮子被遮挡视为正常实际生产中需结合连续帧 by (ball[0].xyxy[0][1] ball[0].xyxy[0][3]) / 2 # 浮子在刻度盘底部的相对位置 ratio (by - y1) / (y2 - y1) return ratio代码的核心是将浮子中心点的 y 坐标映射到刻度盘的 y 区间里得到 0 到 1 的液位高度比例。这个比例乘以量程就是实际液位值。实际使用中浮子的颜色、反光会影响检测稳定所以异常判断不依赖单帧而是缓存最近 5~10 帧的比例值做滑动平均。如果发现连续多帧 ratio 0.9 或 0.1就触发异常告警。该方案同样适用于判断油水界面只要把训练数据的类别改成「油面」「乳化层」并在 yaml 里同步修改即可。4. 可视化界面与数据库实时监控和异常记录联动4.1 PySide6 界面架构把检测结果搬到桌面应用标题里写了「可视化界面」检索热词里也有 python 爬虫可视化界面、jenkins 可视化界面这类词说明读者对界面的普遍认知是「有窗口、有图表、能操作」。对于这个系统用 PySide6 做桌面端比用 Flask 做 Web 端更适合——部署时只需要一台连着摄像头的工业 PC不需要单独配 Nginx 和 Redis课程设计演示也更直观。界面模块建议拆成 4 个区域视频流显示区、实时检测参数区、异常记录表、系统控制按钮。# 主界面骨架PySide6 简化版 import sys from PySide6.QtWidgets import * from PySide6.QtCore import QTimer, Qt from PySide6.QtGui import QImage, QPixmap class TankMonitorWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(储罐液位异常监测系统) self.video_label QLabel(self) self.log_table QTableWidget(self) self.log_table.setColumnCount(4) self.log_table.setHorizontalHeaderLabels([时间, 液位高度, 状态, 截图路径]) self.timer QTimer(self) self.timer.timeout.connect(self.update_frame) start_btn QPushButton(启动监控, self) start_btn.clicked.connect(lambda: self.timer.start(100)) def update_frame(self): # 调用推理函数并刷新画面具体实现见下文 passQTimer 的 100 毫秒间隔是考虑了 YOLOv8s 在 GTX 1660 Ti 上推理耗时约 80~120ms课程设计的帧率要求不高100ms 更新一次刚好。如果用 CPU 跑这个间隔需要拉到 500ms 以上否则界面会明显卡顿。log_table用来存储每次触发告警的关键信息这个设计让「异常检测」不只是闪现一下而是留下可追溯的记录这也是毕设答辩时比较加分的点。4.2 异常记录存储SQLite 和 MQTT 推送检测到异常后需要把告警事件持久化。SQLite 是零配置选择不需要单独装数据库服务。下面代码完成两件事把告警写入本地库同时通过 MQTT 推送到远端监控平台。import sqlite3, datetime, json import paho.mqtt.client as mqtt conn sqlite3.connect(tank_monitor.db) conn.execute(CREATE TABLE IF NOT EXISTS alarm_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, time TEXT, level REAL, status TEXT, image_path TEXT )) def trigger_alarm(level_ratio, frame_save_path): ts datetime.datetime.now().strftime(%Y-%m-%d %H:%M:%S) alarm_status high if level_ratio 0.9 else low conn.execute( INSERT INTO alarm_log (time, level, status, image_path) VALUES (?, ?, ?, ?), (ts, level_ratio, alarm_status, frame_save_path) ) conn.commit() # MQTT 推送 client mqtt.Client() client.connect(192.168.1.100, 1883, 60) payload json.dumps({time: ts, level: level_ratio, status: alarm_status}) client.publish(tank/alarm, payload) client.disconnect()MQTT 是工业监控场景最常见的传输协议,断开网络时消息会丢失对于课程设计足够了。生产环境的做法是加一个 Redis 缓存做断线续传同时把level_ratio换算成实际液位——量程乘以比例即可但很多项目在部署时忘了这一步只存了 0.85 这种无单位的值回看日志根本不知道是多少米。建议在data.yaml旁边加一个range.txt存量程脚本启动时读入告警记录里直接写米。5. 模型优化方向head 改进和 EIOU Loss 适配YOLOv8 在这个任务上的原始表现通常已经够用但工业场景对漏检率的要求更苛刻。如果发现低液位时浮子被罐体边缘遮挡导致漏检先别急着换 YOLOv11优先做两件事改进 head 里的小目标检测分支以及换损失函数。5.1 增加 P2 检测层提升小目标召回率YOLOv8s 的 neck 输出是 P3、P4、P5 三个尺度分别对应 80x80、40x40、20x20 的特征图。液位计的浮子像素面积可能只有 15x15属于小目标P3 层对应原图的 8 倍下采样敏感度不够。常见做法是在 neck 里增加 P2 层160x160代价是推理速度约增加 20%。5.2 EIOU Loss 优化边界框回归YOLOv8 默认用 CIoU 作为回归损失CIoU 对长宽比的惩罚项在某些场景下会让损失震荡。如果模型能收敛但边框不够紧凑比如浮子框总比实际大一圈可以考虑换成 EIOU它把长宽比拆开计算收敛更平滑。Ultralytics 的 repo 允许在 yaml 里手动指定 loss 类型。# 使用已有权重训练时指定 EIOU Loss 的等效做法 yolo detect train \ modelyolov8s.pt \ datadatasets/tank_liquid/data.yaml \ imgsz640 \ epochs80 \ batch16 \ cos_lrTrue # 用余弦退火学习率配合 EIOU 更稳cos_lrTrue搭配降低后的lr00.005可以让 loss 后期收敛更圆滑。注意换 Loss 后不要直接加载旧权重继续训常见做法是完全从头训 80 轮以上否则两种损失函数的梯度尺度不一致loss 可能炸掉。如果训练时间不允许保守方案是不动 Loss优先把精力放在数据上。6. 部署排错与验证技巧同一套训练配置在两台机器上的不同结果标题里强调「简单部署即可运行」但实际部署时出现的问题往往不是模型本身而是环境差异。以下是核心验证和排错的几个节点。先看环境一致性。训练用的 CUDA 版本和推理机必须一致比如训练用 CUDA 11.8部署机上只装了 CUDA 12.x那么在推理机上重新装一次 torch 即可pip uninstall torch torchvision -y pip install torch2.1.2 torchvision0.16.2 --index-url https://download.pytorch.org/whl/cu118然后验证 GPU 是否生效python -c import torch; print(torch.cuda.is_available())如果这条命令输出False优先查 nvidia-smi 显示的驱动版本是否支持该 CUDA 运行时。驱动在 520 以上的机器一般没问题U 盘安装的 Ubuntu 服务器经常缺驱动这是部署失败的最大来源。画损失函数曲线只是训练验证的一个环节推理部署验证要看「连续帧稳定性」——单帧检测准不代表视频流检测准。这里用一个连续 30 帧的测试方法# 从现场视频中截取 30 帧分别检测统计漏检帧数 import cv2 from ultralytics import YOLO model YOLO(best.pt) cap cv2.VideoCapture(test_video.mp4) missed 0 total 0 while cap.isOpened(): ret, frame cap.read() if not ret: break total 1 results model(frame, conf0.3, verboseFalse)[0] if len(results.boxes) 0: missed 1 if total 30: break cap.release() print(fMissed ratio: {missed / total:.2f})当漏检率超过 5% 时不要盲目加训练轮次先检查是不是imgsz和训练时不匹配——推理时把imgsz调成 960 常常能直接降漏检因为浮子在 640 分辨率下太模糊。另外一个现象很常见同一套配置在 A 机器上 mAP 0.75在 B 机器上只有 0.6。这通常不是模型问题而是评测时开了halfTrue但 B 机器的 GPU 不支持 FP16老款 GTX 10 系列。在验证脚本里显式设置halfFalse并关闭amp后对比结果。参数层面的建议是保持conf0.3, iou0.5做最终部署。课设 demo 时为了好看可以把conf拉到 0.5框的置信度更高画面上看起来更利落但在真实采集的视频流上评估时一定要用 0.3否则低对比度光线下的漏检会被掩盖。部署完成后的最后一件事用录像回放模拟现场异常工况把水位从正常逐步升到满量程看系统能不能在 2 秒内触发告警并写入数据库。这个回放测试只测功能链路不测模型能力但它决定了答辩现场演示时系统会不会在关键时刻掉链子。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Argo CD 通知故障排查:从 “Failed to parse new settings“ 到 “Failed to notify recipient“ 的完整诊断指南 2026/9/13 6:53:44

Argo CD 通知故障排查:从 “Failed to parse new settings“ 到 “Failed to notify recipient“ 的完整诊断指南

Argo CD 通知故障排查:从 "Failed to parse new settings" 到 "Failed to notify recipient" 的完整诊断指南 【免费下载链接】argo-cd Declarative Continuous Deployment for Kubernetes 项目地址: https://gitcode.com/GitHub_Trending/ar…

阅读更多 →
图表设计实战指南:从工具选型到布局配色的完整方法论 2026/9/13 6:53:44

图表设计实战指南:从工具选型到布局配色的完整方法论

“diagram-design”这个词,你单独看,会觉得它不过是“画图”的外文说法,但真把它放到项目里去较真,你会发现它是一门被严重低估的功夫。同一个系统让不同人去画,有人三张图讲不清一次调用链路,有人一张图就…

阅读更多 →
图表设计实战指南:从架构图到流程图的类型、配色与布局方法论 2026/9/13 6:53:44

图表设计实战指南:从架构图到流程图的类型、配色与布局方法论

写这篇东西之前,我想先讲一个真实场景。两年前我给团队新人做系统讲解,提前画了一张自以为很详细的架构图,结果对方盯着屏幕看了半分钟,问了一句:“这几个框为什么有的粗有的细?箭头和虚线到底哪个表示调用…

阅读更多 →
Cilium `cilium-dbg map get` 命令详解:查看 BPF Map 用户态缓存内容 2026/9/13 6:53:44

Cilium `cilium-dbg map get` 命令详解:查看 BPF Map 用户态缓存内容

Cilium cilium-dbg map get 命令详解:查看 BPF Map 用户态缓存内容 【免费下载链接】cilium eBPF-based Networking, Security, and Observability 项目地址: https://gitcode.com/GitHub_Trending/ci/cilium cilium-dbg map get 是 Cilium 调试工具集中用于…

阅读更多 →
text-to-cad:重构机械设计的语义工作流 2026/9/13 6:53:44

text-to-cad:重构机械设计的语义工作流

1. 什么是text-to-cad?它不是“用文字画CAD”,而是重构设计工作流的底层逻辑你搜“text-to-cad”时,看到的大多是零散提问:cad下载、cad画直线显示2.1616e、solidworks导入step、cad标注卡住……这些看似琐碎的问题,恰…

阅读更多 →
MoE模型在数据稀缺下的重复过拟合问题解析 2026/9/13 6:50:44

MoE模型在数据稀缺下的重复过拟合问题解析

1. 项目概述:当数据稀缺遇上专家模型,过拟合为何会“认准一个样本地反复咀嚼”“Data Scarcity and Model Sparsity: Mixtures-of-Experts Overfit More to Repeated Data”——这个标题不是一篇泛泛而谈的理论综述,而是直击当前大模型落地中…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞