ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

输电线绝缘子缺陷检测数据集解析:从标注检查到YOLOv8训练实践

输电线绝缘子缺陷检测数据集解析:从标注检查到YOLOv8训练实践 简介面向输电线路巡检与目标检测实战的一套绝缘子缺陷检测数据集采用YOLO格式存储类别为defect适合练习YOLOv5等模型训练与数据划分流程也适用于电力设备缺陷检测相关课题。压缩包共1203个文件以600张jpg图像和601个txt文件为主体内含每张图片对应的YOLO标签及class类别定义另附1个py可视化脚本与1张示例图整体约42.88MB。数据已做划分训练集约480张、验证集约120张标签与图像一一对应。可视化脚本无需修改随机传入一张图片即可绘制边界框并保存结果便于快速校验标注质量。数据集精简紧凑配合作者YOLOv5改进实战专栏可完成从数据准备、可视化检查到模型训练调优的完整流程已有123人浏览学习适合刚入门目标检测或需要绝缘子缺陷样本的开发者直接使用。1. 输电线绝缘子缺陷检测数据集先看清这份数据值不值得下“目标检测数据集”和“输电线绝缘子缺陷”这两个词拼在一起基本就是在告诉检索它的人这是电力巡检、无人机视觉方向用的带标注图片集里面是电线塔上的绝缘子串以及自爆、破损、污闪这类缺陷的框。解压之后你大概率会看到 images 和 labels 目录、类别 class 文件以及一两个数据可视化脚本脚本里已经把训练集、验证集、测试集划分好了。这类数据集的受众很明确做电力巡检算法的工程师、搞巡检产品端落地的小团队以及课题方向是细粒度目标检测的学生。它帮你省掉的不是“训练”那一步而是从零开始拍图、清洗、标注、划分的两三个月。这篇就顺着标题拆开讲图像和标签怎么组织、class 文件为什么不能乱动、可视化脚本到底在查什么、数据划分有哪些暗坑最后用 YOLOv8 跑通一个半小时内的最小验证闭环。适合想拿现成数据快速验证流程、而不是从头攒数据的你。2. 从图像到标注绝缘子数据集的构成、标签格式与 class 文件先解决“这份数据里到底有什么”的问题。标题里写着“包含数据、标签、类别 class 文件”这三样东西组合起来就是一份可以直接喂给 YOLO 系模型的标准数据集。但目录结构看得懂不代表标签体系经得起推敲这一章把构成讲透再动手。2.1 图像来源与目标形态先分清检测对象是绝缘子还是缺陷图像这侧输电线绝缘子缺陷检测的数据绝大多数来自可见光拍摄一部分来自无人机巡检视角少部分有红外热像。拍摄距离决定了目标尺度绝缘子串在画面里可能占三分之一也可能是远处一个小点缺陷就更小。所以拿到数据先看一眼图像分辨率如果大多是 4000×3000 这种无人机原图后续训练前大概率要做切片这个在第 6 章展开。标注层面有两类常见做法。第一类只标缺陷本身比如破损、自爆、异物悬挂第二类同时标绝缘子和缺陷把绝缘子串整体作为父类缺陷作为子类。标题写“绝缘子缺陷图像检测”多数情况下是后者但你需要确认。我见过不少标称为“缺陷检测”的数据集实际只有缺陷类没有正常类训练出来的模型会在现场表现非常神经质——因为每张图都只告诉它“这些是坏东西”背景里大量正常的绝缘子全成了隐性负样本。一个常见类别示例按 classes 的索引顺序排列索引类别名物理特征检测难点0normal完好的绝缘子串伞裙完整背景复杂电线杆塔干扰1defect自爆、破损、裂纹、污闪痕迹目标极小长尾分布严重如果你拿到的数据把 defect 细分成了自爆、破损、污闪多个类别恭喜但要做好类别严重不平衡的心理准备。自爆类目通常只有几十个框全靠其他类别撑量。2.2 标签与 class 文件YOLO 五列 txt 与索引错位的“软标签”标题里的“标签”绝大多数情况下指 YOLO 格式的 .txt 文件。每个 txt 和一张图像同前缀后缀不同比如 10001.jpg 对应 10001.txt。txt 每行一个目标格式是五个数class_id x_center y_center width height注意 x_center、y_center、width、height 全部是归一化到 0~1 之间的比例值除以过图像宽高。这里是最容易出事故的地方——有人拿像素坐标直接写进 txt有人把中心点格式和左上角格式混用训练时都不报错但 mAP 永远不正常。可视化脚本一眼就能看出这种问题第 3 章讲具体方法。class 文件、txt 标签、数据目录三者必须严格对齐。classes.txt 里的顺序一旦固定任何一行都不能删、不能插。如果在文件头部加了一行新类别后面所有 txt 里的数字索引意思全变这就是典型的“软标签”事故文件还在坐标也对但语义全错。处理这类数据集时我习惯先写个检查脚本遍历所有 txt取类别索引最大值 N再读 classes.txt 确认它至少有 N1 行。否则必然存在标签引用了不存在的类别训练时会被静默忽略或报索引错。2.3 标注工具与补标方案LabelImg、X-AnyLabeling 怎么选目标检测常用标注工具就那几个LabelImg 老牌稳定PyQt 界面能直接导出 YOLO 格式X-AnyLabeling 带 AI 辅助标注适合大图里框小目标Roboflow 在线协作方便但私有数据要注意上传合规。这份数据集既然自带标签和 class 文件大概率是 LabelImg 或 X-AnyLabeling 导出的 YOLO 目录结构。如果要自己补标注我的建议是用 LabelImg 打开原图保存时选 YOLO 格式它会自动创建或复用 classes.txt。X-AnyLabeling 可以加载已有 YOLO 目录直接读进现有划分补漏标、修正错框都用它。千万别混存 VOC 和 YOLO 两种格式同一份数据在两种格式之间来回转几次坐标小数点误差会累积小目标框直接偏出半个身位。补充一句绝缘子缺陷数据里漏标率通常比错标率高。原因是自爆和破损在视觉上确实模糊标注员容易漏掉远处小目标这类漏标只能靠可视化抽查和人眼复核兜底。3. 数据可视化脚本三个检查动作让标注质量现原形标题里把“数据可视化脚本”单独列出来说明它在数据集里的地位不低。可视化脚本不是锦上添花而是第一个质检关卡——把不可见的标注错误变成肉眼可见的图形10 分钟就能判断这份数据能不能用。3.1 画框脚本把 txt 标签叠加回原图第一件事是把标注框叠回图像上人眼扫一遍确认坐标归一化是否正确、框是否贴合目标、标签和图像是否错位。常见做法是用 OpenCV 画矩形顺手把类别名写在框上方。代码不复杂但信息量很大import os import cv2 img_dir images/train lab_dir labels/train out_dir visual_check/train os.makedirs(out_dir, exist_okTrue) classes [c.strip() for c in open(classes.txt, encodingutf-8)] for img_name in os.listdir(img_dir): if not img_name.lower().endswith(.jpg): continue stem os.path.splitext(img_name)[0] txt_path os.path.join(lab_dir, stem .txt) if not os.path.exists(txt_path): print(f[缺少标签] {img_name}) continue img cv2.imread(os.path.join(img_dir, img_name)) h, w img.shape[:2] # 按每张图自己的宽高还原坐标别用固定值 for line in open(txt_path, encodingutf-8): parts line.strip().split() if len(parts) ! 5: print(f[坏行] {txt_path}: {line}) continue cls int(parts[0]) x_c, y_c float(parts[1]) * w, float(parts[2]) * h bw, bh float(parts[3]) * w, float(parts[4]) * h x1, y1 int(x_c - bw / 2), int(y_c - bh / 2) x2, y2 int(x_c bw / 2), int(y_c bh / 2) color (0, 255, 0) if cls 0 else (0, 0, 255) cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) cv2.putText(img, classes[cls], (x1, max(0, y1 - 6)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) cv2.imwrite(os.path.join(out_dir, img_name), img) print(done)这段脚本的逻辑按同名前缀匹配图片和 txt读训练集目录下所有 jpg关键一步是拿到每张图自己的宽高再回推像素坐标绝不能从配置文件里读固定尺寸类别名从 classes 列表里取如果框上的文字和实际物体对不上说明索引错位问题当场暴露。你可以调的参数主要是框粗细、颜色映射以及是否需要输出缩略图——图多的时候生成缩略图拼版比一张张翻效率高。3.2 类别分布统计不平衡是验证集失真的源头第二件事是统计。一张类别分布柱状图能直接决定训练策略——要不要做类别均衡采样、要不要加 loss 权重、要不要用复制粘贴增强。统计脚本比画框更简单from glob import glob from collections import Counter cls_counter Counter() size_counter [] for txt in glob(labels/train/*.txt): for line in open(txt, encodingutf-8): parts line.strip().split() if len(parts) ! 5: continue cls_counter[int(parts[0])] 1 size_counter.append((float(parts[3]), float(parts[4]))) print(类别分布:, cls_counter) print(目标总数:, sum(cls_counter.values()))这段统计的是目标框个数不是图片张数因为模型学习的是框。绝缘子缺陷数据集最常见的天平失衡是 normal 类占比超过 70%defect 类只有几个百分点典型长尾。如果 defect 的框总数少于 100你后面调精度调得再狠也救不回来不如先去补充样本或者改换检测策略——先检测绝缘子再对绝缘子区域做缺陷分类。除了类别分布还可以统计宽高比。绝缘子串通常是狭长条宽高比极端如果统计里混进大量接近 1:1 的框就要警惕是不是把整张图或别的物体误标了。3.3 批量质检输出坏图清单比图库本身更重要可视化脚本最好还输出一份坏图清单记录几类问题txt 缺失、行数不是五列、归一化坐标越界、宽高为 0 或负值。检查下载来的数据集时直接看清单文件就知道干不干净不用把一千张图全翻一遍。注意YOLO 训练对坐标越界是容忍的会按图像边界裁剪但越界的框参与计算会让 val 指标虚高。质检时把越界行单列出来人工判断是修坐标还是删掉。图片尺寸不一致也要留意。无人机拍的绝缘子图可能既有 4000×3000 的原图也有裁剪后的 640×640 切片可视化脚本必须按每张图自己的 shape 回推坐标不能假设所有图同尺寸。这也是我上一步代码里特意标注“按每张图自己的宽高”的原因。4. 数据划分train/val/test 怎么切才不漏标、不串帧标题专门注明“已做数据划分”说明它不是一张全量图加一个标签文件夹就完事而是按训练习惯拆好了子集。但对使用方来说划分本身也可能埋雷——不合理划分会让验证指标虚高这份数据的可信度直接腰斩。4.1 三种划分模式按文件列表、按目录、按分组常见的数据划分做法有三种。第一种是维护 train.txt / val.txt / test.txt 三个文本文件里面存图片路径dataset yaml 里用路径引用。第二种是按目录划分images/train、images/val、images/testlabels 目录对应拆成 labels/train 等。第三种是按分组划分以杆塔编号、拍摄架次作为分组单位整个组进同一边。对绝缘子缺陷检测我更推荐第三种思路。同一串绝缘子会被无人机从不同角度拍几十张如果按文件名随机切训练集和验证集里会出现几乎一模一样的目标val mAP 虚高模型实际是靠记忆而不是泛化。标题里的“已做数据划分”在使用前要看它按什么切的——如果只有 train/val 两个目录而没有组信息当 baseline 用可以但不能作为产品验收的指标依据。划分方式适用场景泄漏风险文件列表数据量小、图像独立中目录划分YOLO 系列标准做法中分组划分无人机巡检、连续帧数据低4.2 同源图像与视频帧泄漏划分前先查重这是我在这方向上最大的血泪经验。绝缘子缺陷数据大多来自无人机巡检视频飞机在空中一停一悬停就连续拍几十帧如果划分脚本只做随机拆分同一悬停点的十几帧会被分到训练和验证两个集合里模型靠记忆就能拿高分验证指标大约虚高 10 到 15 个点。这比标注错误更难发现因为训练过程一切正常。解决办法是划分前做图像查重。轻量做法是感知哈希用 dhash 比较图像内容相似度from PIL import Image import imagehash def dhash(path, hash_size8): return imagehash.dhash(Image.open(path).convert(L), hash_sizehash_size) hashes {} for img in all_images: h dhash(img) if h in hashes: print(f[疑似重复] {img} 与 {hashes[h]} 相似) else: hashes[h] img逻辑说明先把图像转灰度、缩到 8×8 网格计算差异哈希然后比较两个哈希值的汉明距离距离小于阈值就判定为近似重复。参数 hash_size8 是常用起点值越大越敏感但计算越慢真实场景里我会把阈值放到 10 以内专门捕捉无人机悬停产生的连拍帧。巡检视频抽帧时也建议每隔几帧抽一张从源头降低冗余。这个哈希对比步骤不要放到划分之后否则得返工。4.3 划分脚本分层采样与划分质量检查如果数据没有同源问题或者查重后已经清理干净剩下的用分层采样保证类别比例稳定。常见比例是 train:val:test 8:1:1 或 7:2:1我一般用 8:1:1因为缺陷样本少val 和 test 各占一成已经接近极限再多就会让稀有类别在验证集里只剩几个框。from sklearn.model_selection import train_test_split # files 是全部图片路径列表先排序再切保证结果可复现 files sorted(read_all_image_files()) train_files, test_files train_test_split( files, test_size0.2, random_state42, stratifyNone) val_files, test_files train_test_split( test_files, test_size0.5, random_state42, stratifyNone)需要先 pip install scikit-learn。这里没有用 stratify因为按缺陷类别做分层需要为每张图分配一个标签而目标检测一张图里有多个框、多种类别很难干净地映射成单标签。如果数据只有几百张更不要强行分层否则 val 里某个类别只剩一两张图比不均衡更糟。random_state 固定为 42是为了让每一次重跑脚本得到相同的划分结果这是数据划分的基本素质——别人的实验要在你的数据上复现划分就不能每次都不一样。划分完还有一个验收动作把三个子集的类别分布各自打印一遍对比 train 和 val 的类别比例差值在正负 5% 以内算合格。如果 defect 在 train 里占 8%、在 val 里只有 2%说明这次划分不均衡模型在 val 上的表现不可信。5. 避坑与常见问题排查5 个在绝缘子数据集上翻过车的点前几章讲流程这一章讲故障。下面五条都是处理绝缘子数据集时真正踩过的坑按“现象→原因→解决”写每条都能对应到一条可执行检查。5.1 现象训练 loss 降不下去val mAP 卡在 20% 附近原因多半是正样本太少。缺陷类别占比极低模型倾向于把一切预测成背景loss 前期下降后期直接平台期。这不是算法问题是数据分布问题。解决先跑一遍 3.2 的类别统计确认稀有类别框数。如果少于 100优先做图片级过采样配合 mosaic 增强提高采样率再不行就换检测策略两阶段检测——第一段只找绝缘子第二段在绝缘子区域里做缺陷分类。这两种改法都比硬调损失函数权重见效快。5.2 现象可视化画出的框整体偏左上或偏右下原因基本是 txt 里存的是左上角加宽高的 VOC 格式脚本却按中心点 xywh 去解析。这类事故常发生在 VOC 转 YOLO 的转换脚本上转换时切错字段。解决找一张实际框位置明确的图用脚本打印出该行五个数值对比目标真实中心点判断格式。如果算出来的中心点明显偏左上说明前两个数其实是 xmin、ymin需要按 x_center xmin w / 2 做偏移修正。一次性批量改完再跑可视化复核。5.3 现象训练正常、可视化正常但 predict 结果类别张冠李戴比如把自爆缺陷框标成了正常绝缘子。这是典型的索引错位事故。原因常常是 classes.txt 被人往头部插了一行所有类别索引整体 1旧标签的数字含义全变。标签像素没问题语义全错就是前面说的“软标签”。解决classes.txt 顺序一旦确定一行都不许动。真要追加类别追加到文件末尾同时用脚本把 txt 里的类别号批量更新为新索引# 新增类别后把旧索引 2 的保持 2 的统一 1 for txt in glob(labels/train/*.txt): lines open(txt, encodingutf-8).readlines() with open(txt, w, encodingutf-8) as f: for line in lines: parts line.strip().split() cls int(parts[0]) if cls 2: parts[0] str(cls 1) f.write( .join(parts) \n)这段代码把旧索引中大于等于 2 的类别整体后移一位保持旧标注的有效性参数“2”是原来类别总数按实际情况改。关键提醒改之前先备份 classes.txt 和 labels 目录这个操作不可逆没有后悔药。5.4 现象训练启动时报 image not found 或 label not found原因通常是 images 和 labels 两个目录的前缀对不上。可能某张图被删了但标签没删或者从 Windows 复制到 Linux 后文件名大小写不一致也可能是 txt 里夹了一个 BOM 头导致读取失败。解决写个同步检查脚本遍历两个目录分别输出“有图无标签”和“有标签无图”的文件名清单。注意别在脚本里直接删文件先人工看一眼清单确认不是大写的 .JPG 和后缀 .jpg 这种大小写问题再处理。5.5 现象val mAP 高得好看现场一换杆塔就漏检这是最具迷惑性的坑。原因在数据划分阶段就埋下了——同一杆塔、同一次巡检的图片被随机分到了 train 和 val模型记住的是具体图像而不是绝缘子缺陷的泛化特征。现场换一组杆塔、换个拍摄角度立刻露馅。解决回到 4.1 说的分组划分。如果数据集的原始目录结构是按杆塔或架次组织的就不要用随机划分按组切分。这一步会牺牲一点 val 指标的数字但得到的模型更接近真实产品表现。验证时也可以故意挑一组完全没有参与训练的杆塔图片做测试看看指标掉多少掉得少才是真泛化。6. 用划分好的数据跑通最小训练闭环YOLOv8 目标检测的半小时验证数据检查、可视化、划分都过了最后一章说怎么把它变成第一次训练。这里的流程就是平时处理数据集用于 YOLOv8 训练的常见做法半小时内能判断这份数据值不值得继续投入。第一步建 dataset.yaml路径指向划分出来的目录。如果你的 classes.txt 里只有 normal 和 defect 两类配置就这样写path: /data/insulator train: images/train val: images/val test: images/test nc: 2 names: [normal, defect]第二步启动训练。用 YOLOv8 的话ultralytics 包版本要固定别追新我一般锁 8.0.x 系列yolo taskdetect modetrain modelyolov8n.pt datadataset.yaml epochs50 imgsz640 batch16先用 nano 权重验证数据和配置通不通跑 50 轮。如果 loss 在 10 轮以内正常下降说明数据格式没问题再换 s 或 m 规模迭代。imgsz640 是默认值但绝缘子无人机原图动辄 4000×3000直接缩放会把小缺陷抹掉这种情况建议先做切片把原图裁成 640 或 960 的 patch再喂给模型小缺陷的相对尺寸变大检测效果比整图缩放好得多。第三步验证。训练完先跑 val 拿 mAP50 和 mAP50-95然后用第 3 章的可视化脚本对推理结果重新画框人眼抽查 10 张左右——框有没有漏、位置贴不贴缺陷边缘。抽查能过这份数据才算真正用起来。说到底目标检测数据集的价值从来不取决于下载按钮而取决于标签准不准、划分干不干净、可视化能不能复查。我个人的习惯是任何一份绝缘子数据到手先跑可视化拿分布图和坏图清单再动训练——这半小时的“慢”换来的是后面少踩整周的坑。希望帮到你。本文还有配套的精品资源点击获取
返回列表