新闻详情

新闻详情

首页 / 资讯中心 / 详情

YOLO实战:237张汽油泄漏图像全流程检测与避坑指南

发布时间:2026/10/2 9:48:04来源:尧图网络
YOLO实战:237张汽油泄漏图像全流程检测与避坑指南
简介该数据集面向计算机视觉目标检测任务聚焦汽油泄漏检测场景提供237张JPEG图片及对应的Pascal VOC和YOLO两种格式标注。数据集共标注两个类别petrol汽油与water水总计306个目标框其中petrol框212个、water框94个全部由labelImg工具按矩形框标注完成。需留意的是真实汽油泄漏图像稀缺多数图片为数据增强生成选用前可结合预览图仔细甄别。资源以7z格式打包共713个文件具体包含237个jpg、237个xml和239个txtjpg为原始图像xml与txt分别对应VOC和YOLO格式标签解压后即可用于YOLO、Faster R-CNN等常见检测模型的训练与验证。整个包体仅16.61MB轻量便捷页面已有288人学习下载。数据集本身仅保证标注准确合理并不对训练出的模型精度作任何承诺适合作为目标检测入门练习或特定场景数据补充。1. 汽油泄漏检测数据集237 张图为什么值得你先跑通 YOLO 全流程石化厂区巡检摄像头拍到的接油盘、管道法兰处油污和滴落经常只有几十像素大人眼盯监控屏容易漏。你想先用现有数据验证一下“汽油泄漏能不能用 YOLO 检测”手里最缺的不是模型而是一份干净、带 VOC 和 YOLO 两套标注的小数据集。这个 .7z 存档就是为这个场景准备的237 张现场图像二分类——通常是“油液泄漏”和“正常/背景”两类而且 VOC XML 和 YOLO txt 两套标注都给了。数据量不大但小样本正是很多实际项目起步时的状态用它先跑通“标注检查 → 数据集划分 → YOLO 训练 → 视频推理”全流程比等攒到 2000 张再启动更务实。适合刚接手视觉检测的工程师、做毕设或竞赛的学生也适合想评估 YOLO 在反光、小目标场景下能到多少分的从业者。2. 拆开 .7z 看数据VOC 和 YOLO 标注的目录结构与参数含义2.1 两种标注格式并存各自解决什么VOC 格式全称 Pascal VOC是 2012 年那批检测竞赛带起来的标准之一。每张图对应一个同名 XML物体位置用bndbox里的xmin/ymin/xmax/ymax绝对像素坐标表达。YOLO 格式则是 Darknet 和 Ultralytics 系训练器默认读的纯文本每行一个目标依次是class_id x_center y_center width height中心坐标和宽高全部除以图片宽高做成了 0~1 小数。一个数据集同时给两套实际上是为不同工具链准备的。早期做检测的人用 LabelImg 打标出来就是 VOC XML后来 YOLO 系训练器只认 txt于是大量项目要把 XML 转 txt。这个 237 张的包两套都给了下载后可以省掉转换这一层直接用 VOC 做可视化校验、用 YOLO 做训练。两套格式不是等比关系VOC 还能记录truncated、difficult这些属性YOLO txt 没有这些位所以从 VOC 转 YOLO 时那些被截断、遮挡、模糊的目标优先级信息会丢。提示拿到包先不要直接解压到训练目录。先找一个空白目录解压后把classes.txt和任一 XML 打开看一眼确认类别顺序再决定脚本怎么写。两种格式的差异可以用表格总结维度VOC XMLYOLO txt坐标表示像素绝对坐标图像相对坐标0~1类别表达nameleak/name数字索引0 开始附加属性truncated/difficult 可选无常用工具LabelImg、MMDetection 兼容转换Ultralytics YOLO 直接读取这里最容易出错的是“类别顺序”。YOLO txt 只有数字没有名字0到底指leak还是normal只取决于classes.txt里的行顺序。如果你从别的地方复制来一个classes.txt恰好顺序和本数据包不一致训练出的结果就会类别错乱。2.2 目录与文件清单先核对再动手解压后目录结构通常长这样. ├── gas_leak_voc │ ├── Annotations │ ├── ImageSets │ └── JPEGImages └── gas_leak_yolo ├── images ├── labels └── classes.txt其中gas_leak_voc/JPEGImages放 237 张原始图Annotations放同名 XMLgas_leak_yolo/images和labels分别是 YOLO 训练的图、标目录classes.txt只写类别名。先用命令确认类别和数量而不是直接丢进训练器cat gas_leak_yolo/classes.txt awk {print $1} gas_leak_yolo/labels/*.txt | sort | uniq -c第一行输出类别名第二行统计每个类索引出现的标注框数。如果第二列数字出现normal只有十几框、leak有几百框说明二分类并不均衡后面训练要单独考虑。另外要确认图片后缀.jpg、.png都可能有后面检查脚本的 glob 模式要同步改。如果包里的 VOC 部分带ImageSets/Main里面通常有train.txt、val.txt。这个文件保存的是不带后缀的图片名不同来源的 ImageSets 划分不一致不建议直接用。自己重新按 3.1 的方式划分哪怕多写几行脚本也比盲信自带的划分可靠。2.3 标注文件长什么样XML 和 txt 逐行拆解打开一个 XML 标注内容类似这样annotation filenameg001_frame_012.jpg/filename size width1920/width height1080/height depth3/depth /size object nameleak/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin634/xmin ymin482/ymin xmax715/xmax ymax541/ymax /bndbox /object /annotation这个框标注的是图片里一块明显的汽油泄漏油渍左上角在 (634, 482)右下角在 (715, 541)框宽 81 像素、高 59 像素。把宽高和图片分辨率 1920x1080 放在一起能看出目标占画面不到 0.3%这是泄漏检测很典型的情况目标小、和背景对比度低训练时需重点看小目标指标。对应到 YOLO 格式这同一个框会写成# classes.txt 内容两行 leak normal # 对应标注 g001_frame_012.txt 0 0.35130 0.47361 0.04219 0.05463计算并不复杂x 中心(634715)/2674.5除以 1920 得 0.35130y 中心(482541)/2511.5除以 1080 得 0.47361宽(715-634)81除以 1920 得 0.04219高(541-482)59除以 1080 得 0.05463。注意这里用的是中心点加宽高不是左上右下很多人第一次看 txt 时会把w当成右下角 x直接导致框偏移。提示YOLO 坐标用 float 表示有效位数保留 6 位基本够用。因为最终训练时会再次缩放到模型输入尺寸0.000001 的误差在 640 像素图上只影响不到 1 像素的偏移。2.4 用脚本快速验证 VOC 和 YOLO 是否真的同步两套标注在理论上是同一个框的两种写法但来源复杂的包可能出现过一次转换后没同步的问题。我一般会跑一遍交叉校验看同一张图的 XML 转成 YOLO 坐标后和 txt 里写的差异大不大。import xml.etree.ElementTree as ET from pathlib import Path voc_dir Path(gas_leak_voc) yolo_dir Path(gas_leak_yolo) for xml_path in sorted(voc_dir.glob(Annotations/*.xml)): root ET.parse(xml_path).getroot() w int(root.find(size/width).text) h int(root.find(size/height).text) txt_path yolo_dir / labels / f{xml_path.stem}.txt if not txt_path.exists(): print(fVOC存在但YOLO缺标注: {xml_path.stem}) continue yolo_lines txt_path.read_text().strip().splitlines() voc_objs root.findall(object) for obj in voc_objs: bnd obj.find(bndbox) xmin float(bnd.find(xmin).text) ymin float(bnd.find(ymin).text) xmax float(bnd.find(xmax).text) ymax float(bnd.find(ymax).text) xc ((xmin xmax) / 2) / w yc ((ymin ymax) / 2) / h bw (xmax - xmin) / w bh (ymax - ymin) / h print(f{xml_path.stem}: VOC-YOLO {xc:.5f} {yc:.5f} {bw:.5f} {bh:.5f})逻辑说明脚本没有直接断言而是把 XML 转出来的坐标打印出来你再用diff或肉眼对比 txt 内容。常见的差异来源是 XML 的size和图片真实尺寸不一致导致两边框错位。参数说明这里xml_path.stem是图片同名的主文件名YOLO 目录里的文件名必须一致如果打印结果和 txt 明显不同说明其中一套标注是从旧版图片转换来的训练前必须选定一套做主数据。3. 把 237 张图变成训练集数据划分、完整性校验与增强3.1 按场景分组划分而不是逐帧随机划分237 张图很少随机划分看似公平但如果是从同一段视频里连续抽帧相邻帧画面高度相似随机划分会把几乎一样的图片同时送进训练集和验证集mAP 虚高到 0.9一换新场景立刻打回原形。我一般的做法是先按场景分组再在场景维度上做划分。import random import shutil from collections import defaultdict from pathlib import Path root Path(gas_leak_yolo) out_root Path(gas_leak_split) scene_map defaultdict(list) for img in sorted((root / images).glob(*.jpg)): scene img.name.split(_)[0] # 假设文件名形如 g001_frame_012.jpg scene_map[scene].append(img) scenes list(scene_map.keys()) random.seed(42) random.shuffle(scenes) n len(scenes) n_val int(n * 0.2) n_test int(n * 0.1) for i, scene in enumerate(scenes): split test if i n_test else val if i n_test n_val else train for img in scene_map[scene]: lbl root / labels / f{img.stem}.txt target_img out_root / split / images / img.name target_lbl out_root / split / labels / lbl.name target_img.parent.mkdir(parentsTrue, exist_okTrue) target_lbl.parent.mkdir(parentsTrue, exist_okTrue) shutil.copy2(img, target_img) shutil.copy2(lbl, target_lbl)这段脚本先把同场景的帧归到一个桶里再对场景桶做随机划分复制的图片和同名标一并复制不会出现图片有、标签无的情况。参数说明n_val0.2*n在场景数较小的时候验证集可能只有 3、4 个场景变量仍然可用但要观察验证集的场景多样性。如果你拿到图的文件名根本没有下划线前缀可以先对全量图片做一次感知哈希去重再按哈希前缀分组。3.2 标注完整性校验一行命令和一个小脚本先跑一遍前端的命令确认数量和格式再用脚本把每条标注的数值合法性查一遍。find gas_leak_yolo/images -type f | wc -l find gas_leak_yolo/labels -type f | wc -l两个数字应该相同。如果不相同说明存在图片没有标注或标注没有图片训练时可能被当作空背景。接着用 Python 校验坐标import math from pathlib import Path lbl_dir Path(gas_leak_yolo/labels) img_dir Path(gas_leak_yolo/images) nc 2 for lbl in sorted(lbl_dir.glob(*.txt)): if not (img_dir / f{lbl.stem}.jpg).exists(): print(f缺少图片: {lbl.name}) for line_no, line in enumerate(lbl.read_text().strip().splitlines(), 1): parts line.split() if len(parts) ! 5: print(f列数不对 {lbl.name}:{line_no}) continue try: cls, x, y, w, h map(float, parts) except ValueError: print(f数值非法 {lbl.name}:{line_no}) continue if math.isnan(x) or math.isnan(y): print(fnan坐标 {lbl.name}:{line_no}) if cls 0 or cls nc: print(f类别索引越界 {lbl.name}:{line_no}) if w 0 or h 0 or x w 1.0001 or y h 1.0001: print(f框越界 {lbl.name}:{line_no})逻辑说明YOLO 坐标是中心点加宽高所以判断越界的标准不是x是否在 0~1而是x w 1给 0.0001 的冗余是照顾浮点误差。math.isnan专门抓转格式时产生的非法值这类藏在无数行里的nan是训练nan loss的第一大来源。如果报错行不多直接删掉再跑如果报错成片要考虑整套标注是否被错误脚本重新生成过。3.3 小样本增强同步更新坐标是底线237 张图不够深度学习发挥增强是必须的但增强不是复制粘贴。泄漏本身是液体下落或油渍扩散垂直翻转会把重力方向改掉镜面反射类增强会造出不可能出现在现实里的高光伪影。我一般只做水平翻转、亮度对比度微调、小幅度裁剪且全程用现有增强库保证坐标联动更新。import albumentations as A import cv2 aug A.Compose([ A.HorizontalFlip(p0.5), A.RandomBrightnessContrast(brightness_limit0.15, contrast_limit0.15, p0.3), A.RandomSizedBBoxSafeCrop(width640, height640, p0.2), ], bbox_paramsA.BboxParams(formatyolo)) image cv2.imread(gas_leak_yolo/images/g001_frame_012.jpg) with open(gas_leak_yolo/labels/g001_frame_012.txt) as f: lines f.read().strip().splitlines() boxes [list(map(float, line.split()[1:])) for line in lines] class_ids [int(line.split()[0]) for line in lines] out aug(imageimage, bboxesboxes, class_idsclass_ids) cv2.imwrite(aug_001.jpg, out[image])参数说明bbox_params中formatyolo让库知道输入的是归一化中心点所有变换会同步换算坐标并输出新格式RandomSizedBBoxSafeCrop会尽量让裁剪区域不切掉现有框比普通 RandomCrop 适合小目标。注意最终验证增强效果时要把原始图和增强图都放进同一个 split避免同一目标以不同形态同时存在于训练和验证集又是虚高指标。3.4 划分后的最后一道检查文件名与类别分布划分完目录不要急着训练先确认每个 split 里都有图和标注。ls gas_leak_split/train/images | wc -l ls gas_leak_split/train/labels | wc -l cat gas_leak_split/train/labels/*.txt | awk {print $1} | sort | uniq -c如果某个 split 的labels目录里没有文件训练时 YOLO 会报No labels found in .../images/train。如果train里leak类有 200 个框、normal只有 3 个框那二分类训练大概率学出个“永远预测 leak”的模型得回到前面重新考虑类别合并。4. 避坑VOC 与 YOLO 混用时的五条踩坑记录4.1 现象loss 正常mAP 不动预测框全堆在图片左上角原因VOC XML 里的坐标是像素值YOLO txt 里是 0~1 归一化值。有人把两套数据混在一个训练目录里转格式时没有乘除图片宽高有的框是像素、有的是归一化值模型学出来的坐标一团乱。解决训练前统一格式。如果要用 YOLO 训练全部转成 YOLO并且转换时读图宽高from PIL import Image img_width, img_height Image.open(img_path).size x_center (xmin xmax) / 2 / img_width y_center (ymin ymax) / 2 / img_height width (xmax - xmin) / img_width height (ymax - ymin) / img_height而不是从 XML 里读size因为实际图片可能被压缩过而 XML 没更新。4.2 现象模型的预测结果基本只有一类另一类从未出现原因VOC 里normal类通常存在于背景中标注者往往只框泄漏点normal的标注框数极少类别严重失衡。解决先统计类别数量awk {print $1} gas_leak_yolo/labels/*.txt | sort | uniq -c如果某一类不足 10 个框就不要硬做二分类。可以把第二类合并为背景只保留leak一类改nc1。想要真正做两类检测必须补充第二类带有边界框的样本单纯有图片没框对 YOLO 没有意义。4.3 现象验证集 mAP 0.95换一段视频测试漏检严重原因237 张图可能来自同一段视频随机划分时相邻帧画面高度雷同同场景的画面同时出现在训练和验证里模型其实“背”了场景没有泛化能力。解决如 3.1 所说按场景桶划分。如果没有场景前缀可以用文件名的时间戳或抽样缩略图人工确认。这是小数据集最容易出现“自欺欺人”的坑比调参重要得多。4.4 现象LabelImg 里看 VOC 标注很正常转成 YOLO 后框完全错位原因XML 的size字段和图片真实尺寸不一致。常见于数据集被某脚本压缩过原图宽高被改成 1280x720但 XML 里还写着 1920x1080。解决转换脚本里强制重新读取图片尺寸不要信 XMLfrom PIL import Image from pathlib import Path for xml_path in xml_dir.glob(*.xml): img_path img_dir / f{xml_path.stem}.jpg width, height Image.open(img_path).size拿到新数据集后先随机抽 5 张图把 XML 坐标画上去对比原图肉眼确认框是否贴合。这一步 5 分钟能省下后续整个训练周期。4.5 现象训练到一半出现nan loss代码没动过原因数据里存在非法标注比如某行 txt 是0 0 0 0 0或者坐标出现了nan。YOLO 在数据增强阶段处理这种框时会计算出无穷大反向传播直接把 loss 打成nan。解决训练前跑 3.2 的校验脚本把nan和w 0行全部剔除。很多人会把nan loss归咎于学习率其实小数据加小模型最常见原因就是脏标注。养成习惯训练启动前先做数据校验不要直接敲训练命令。5. 用 YOLO 训起来配置文件、训练命令与结果判读5.1 数据 YAML 怎么写路径和类别是最大的坑在 Ultralytics YOLO 里训练入口是数据 YAML。以 237 张这个数据集的 YOLO 目录为例path: /data/gas_leak # 改成你的实际路径 train: images/train val: images/val nc: 2 names: 0: leak 1: normal逻辑说明path是根目录train、val是相对根目录的图片目录YOLO 会根据图片名在相邻labels目录下找同名 txt。很多人配置错误的点是只写path不写train/val或者把labels路径写进配置trainer 就会去 labels 里找图片直接报错。参数说明nc必须和classes.txt一致names的顺序必须和 txt 里的 class_id 一一对应。如果你按 4.2 决定只训练一类就把nc改成 1names删掉 normal。5.2 训练命令与超参数用小模型先跑通再谈精度237 张不值得一上来跑yolov8x第一轮的目标是流程通、能收敛。用 nano 或 small 模型yolo detect train \ datagas_leak.yaml \ modelyolov8n.pt \ epochs200 \ batch16 \ imgsz640 \ patience30 \ seed42参数说明modelyolov8n.pt表示加载 COCO 预训练权重针对小数据集能显著提速epochs200配合patience30如果 30 轮没有改善会自动停不会白跑batch16是 1080Ti 级别的稳妥值显存小则减到 8。imgsz640是默认但泄漏目标小我建议流程跑通后再用imgsz1024试试通常 mAP50-95 会有几个点提升。如果是 YOLOv5命令等价为python train.py --data gas_leak.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 200 --patience 30第一轮不要开一堆增强和 loss 魔改先把模型当成黑盒子跑通确认数据没问题后面再做精度优化。5.3 结果怎么看光看 mAP50 会漏掉关键信息训练结束后runs/detect/train目录里重点看results.png、confusion_matrix.png和val_batch0_pred.jpg。以 237 张这样的小数据集几个指标合理区间只能参考因为取决于标注质量和场景难度指标含义参考区间mAP50IoU0.5 下的平均精度0.6~0.9mAP50-95更严格的多档 IoU 平均0.25~0.55Precision检出的框里有多少是对的0.85 左右Recall真实泄漏有多少被框住0.8 左右指标不是越高越好。如果 mAP50 高但 mAP50-95 很低说明框的位置贴合度差对泄漏这种小目标意味着部署后框会飘没法直接给现场监控用。如果 val_batch 预测框把地面阴影划成泄漏要做难例挖掘而不是盲目调置信度阈值。5.4 训练中的实时曲线loss 不下降也别急着加 epoch训练时建议开 TensorBoard 看曲线tensorboard --logdir runs/detect/train小数据集的典型情况是 train loss 降得很快val loss 在 80 轮以后不再降甚至抬头。此时加 epoch 没有意义该做的是降低模型复杂度、增加数据增强或补充数据。很多初学者把patience拉满训练 500 轮最后只是浪费时间。6. 让 237 张数据发挥最大价值迁移推理与后续扩展6.1 先用测试视频做推理别急着上生产训练完best.pt后不要只拿 test 集图片看指标。找一段没参与过训练的现场视频用下面的命令推一遍yolo detect predict modelruns/detect/train/weights/best.pt \ sourceleak_video.mp4 \ conf0.25 \ iou0.45 \ imgsz640 \ save_framesTrue逻辑说明conf0.25过滤低置信度框iou0.45是 NMS 参数重叠度高会被合并imgsz必须与训练一致否则尺度变化会直接造成小目标漏检。如果视频里目标闪烁、时有时无先把conf降到 0.15 看是漏检还是阈值太高如果噪声框同样变多问题在训练数据不在推理。6.2 用伪标注把数据集从 237 扩大到上千张我习惯的做法是拿上一步的模型去预测现场未标注帧生成高置信度候选框作为伪标注人工只修正明显错误然后并入训练集。伪标注有一个前提新抽的帧不能和原训练集来自同一场景否则又把记忆当泛化。扩充到 800 张后再跑一轮训练通常 mAP50 会有肉眼可见的提升。237 张是起点不是终点。这个资源最大的意义是你不用从零搭数据管线解压后十几分钟就能把第一版模型跑出来后续把校验脚本、划分脚本、yaml 固定成自己项目里的模板换一个检测场景直接复用。从那以后我拿到任何数据集都会强制先走一遍“classes.txt 核对 → 数量比对 → 非法坐标扫描 → 类别分布统计”再碰训练命令。这一套动作让我省下的返工时间远超过跑几十个 epoch。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

邻接矩阵与邻接表:图的存储结构选型、C语言实现与避坑指南 2026/10/2 10:36:30

邻接矩阵与邻接表:图的存储结构选型、C语言实现与避坑指南

简介:这份资源面向正在学习数据结构中图结构的学生与开发者,聚焦图的两种核心存储方式——邻接矩阵与邻接表,帮助解决二者之间相互转换的实现难题。资源以C语言代码为主线,完整呈现了从邻接矩阵转换为邻接表、再由邻接表转回邻接矩…

阅读更多 →
OpenAI推理集群配置解析:基于AMD 9V74与vLLM的NUMA调优实操 2026/10/2 10:36:24

OpenAI推理集群配置解析:基于AMD 9V74与vLLM的NUMA调优实操

近期关于大型语言模型底层基础设施的讨论在技术社区持续升温。一份被标记为 OpenAI Dot 的虚拟机配置清单在开发者论坛中曝光,其中明确指出了 AMD 霄龙 9V74 处理器以及 9.7 这一关键版本参数。这一配置不仅揭示了大型语言模型在推理阶段的硬件选择倾向,…

阅读更多 →
Linux下npm start后台运行原理与生产部署方案 2026/10/2 10:36:24

Linux下npm start后台运行原理与生产部署方案

1. 项目概述:为什么“npm start”在Linux里一关终端就停?这根本不是bug,是Unix进程模型的天然设计 你刚在服务器上跑起一个Vue或React项目,执行 npm start ,浏览器能正常访问,一切OK。可一旦你关闭SSH终端…

阅读更多 →
高情商沟通的底层逻辑与实战方法:从连接到表达 2026/10/2 10:36:11

高情商沟通的底层逻辑与实战方法:从连接到表达

1. 沟通的底层逻辑:先搞清楚“高情商”到底在解决什么问题 先说个真实感受。我在团队里带过不少人,发现一个特别普遍的误解:很多人觉得高情商沟通就是嘴甜、圆滑、会来事儿,说白了就是“哄人开心”。可真到了工作中你会发现&#…

阅读更多 →
找次品动画演示:HarmonyOS ArkTS状态管理与ArkUI动画实战 2026/10/2 10:36:11

找次品动画演示:HarmonyOS ArkTS状态管理与ArkUI动画实战

前阵子在 DevEco Studio 里刷华为官方示例集,按顺序整理到自己练习库里的时候,正好做到“HarmonyOS 应用实例 97:找次品动画演示”。这个题目一看就很戳我。名字里的“找次品”是小学数学里特别经典的逻辑题:一堆外观完全一样的球…

阅读更多 →
微信商城小程序毕业设计源码解析与前后端MySQL联调实战指南 2026/10/2 10:36:10

微信商城小程序毕业设计源码解析与前后端MySQL联调实战指南

简介:面向高校学生与初学者的微信商城小程序毕业设计源码包,整合了完整前后端、MySQL数据库、说明文档与LW论文,适合毕业设计、课程设计或小程序电商入门实践。项目覆盖商品展示、购物车、下单处理、支付对接与订单管理等核心功能&#xff0c…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

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

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