
简介输电线绝缘子缺陷检测数据集适用于电力巡检场景下的目标检测任务面向希望训练YOLO系列模型的算法工程师与学生。数据已完成划分训练集约480张图片、验证集约120张图片按YOLO文件夹结构保存标签采用YOLO格式共1个类别defect可直接用于模型训练。压缩包共1203个文件以600张jpg图像与601个txt标注为主体另含类别class文件、1个Python可视化脚本和1张png示意图片整体约42.88MB。可视化脚本支持随机读取一张图片绘制边界框并保存到当前目录无需修改即可运行便于快速核对标注效果。目前已有123人学习下载适合作为输电线绝缘子缺陷检测实战的入门数据也便于结合YOLOv5改进实验进行训练与验证。1. 目标检测数据集输电线绝缘子缺陷图像拿到手就能开始训练的那一种电力巡线场景里绝缘子缺陷检测是目标检测落地最典型的需求之一。无人机拍回来的巡检图像里破损、自爆、污闪的绝缘子靠人工一张张盯效率低且容易漏换成YOLO这类检测模型后一张图几十毫秒就能出结果。这个数据集就是干这个用的——它把输电线绝缘子缺陷图像按YOLO文件夹规范整理好了标注格式直接可训练类别就一个defect训练集480张左右、验证集120张左右还附带一个随机取图就能画边界框的可视化脚本。对刚入手目标检测、想跑通一套完整流程的人来说这个数据的价值在于省掉了最繁琐的两步标注和划分。你不需要自己去labelImg里画框也不用手动分train/val下载解压后改一下data.yaml里的路径就能开训。如果你已经在跑YOLOv5或YOLOv8这份数据可以作为绝缘子缺陷检测的入门基准集也可以用来验证你对数据增强、超参数调优的改动是否有效。2. 数据结构与YOLO标注格式先弄清文件夹和txt里藏了什么2.1 目录结构images和labels的镜像对应关系这份数据集按YOLO的标准习惯保存解压后你会看到类似下面的目录布局。文件名是四位数字编号比如0780.jpg、0059.jpg图片和标签一一对应靠相同的主文件名关联。insulator_defect/ ├── images/ │ ├── train/ │ │ ├── 0780.jpg │ │ ├── 0059.jpg │ │ └── ...(约480张) │ └── val/ │ ├── 0108.jpg │ └── ...(约120张) ├── labels/ │ ├── train/ │ │ ├── 0780.txt │ │ ├── 0059.txt │ │ └── ...(与images一一对应) │ └── val/ │ └── ...(约120个txt) ├── classes.txt ├── data.yaml或需要自己写 └── visualize.py这套结构的核心是镜像对应images/train里的每张jpg在labels/train里都有一个同名txt。YOLO训练时就是靠这个命名约定去关联图像和标签的所以解压后不要随意重命名文件更不要让两个目录结构错位。注意有些资源不会自带data.yaml需要根据实际路径手写一份。后面第4章会给模板。2.2 标签txt文件一行一个目标五个数字说明全部信息每个txt文件里每一行代表一个缺陷目标。YOLO格式的标注用的是归一化坐标一行五个值含义固定0 0.483333 0.512963 0.300000 0.237037从左到右分别是类别编号这里只有一个类所以全是0、归一化中心点x坐标、归一化中心点y坐标、归一化宽度、归一化高度。所有坐标值都在0到1之间除以图片宽高做了归一化。我一般会用下面这段代码快速扫描一个标签文件确认坐标范围是否合法import os label_path labels/train/0780.txt with open(label_path, r, encodingutf-8) as f: lines f.readlines() for idx, line in enumerate(lines): parts line.strip().split() if len(parts) ! 5: print(f第{idx1}行格式错误: {line.strip()}) continue class_id, cx, cy, w, h map(float, parts) # 归一化坐标必须在[0,1]区间内 if not (0 cx 1 and 0 cy 1 and 0 w 1 and 0 h 1): print(f第{idx1}行坐标越界: {line.strip()}) if w 0 or h 0: print(f第{idx1}行宽高异常: {line.strip()})这段脚本的逻辑是逐行解析标签先检查字段数量是否为5再检查每个坐标值是否在合法区间最后确认宽高不为0。坐标越界的标签是训练时Loss变成NaN的最常见原因之一第5章会细说。2.3 classes.txt单一类别编号从0开始classes.txt文件内容就一行一个词defect。这决定了模型输出层的类别数nc1。如果后续你想区分“破损缺陷”和“污闪缺陷”那就得修改这个文件并重新标注——那属于数据集扩展我在第6章会讲。YOLO的类别编号从0开始计数所以defect对应编号0所有标签txt里每行行首的类别编号也全是0。如果某天你在标签文件里看到1或者2而classes.txt只有一行那几乎可以断定是标签文件混入或标注工具配置错了。3. 可视化脚本实战不改路径直接看边界框画得准不准3.1 脚本的核心逻辑读图、解析txt、坐标反归一化这份数据集附带的可视化脚本设计目标是“随机传入一张图片即可绘制边界框并保存到当前目录”。它的核心逻辑并不复杂用OpenCV读图找到同名txt把归一化坐标乘以图片宽高还原成像素坐标然后用cv2.rectangle画框最后保存。整个链路拆开看就是四步。第一步读图第二步解析标签第三步坐标转换第四步绘制保存。下面这段代码是可视化脚本的核心骨架import cv2 import os def visualize(image_path, label_path, output_pathoutput.jpg): # 第一步读取图片OpenCV不支持中文路径时会返回None img cv2.imread(image_path) if img is None: print(f图片读取失败: {image_path}) return h, w img.shape[:2] # h为图片高w为图片宽 # 第二步解析同名txt标签文件 with open(label_path, r, encodingutf-8) as f: lines f.readlines() # 第三步逐行将归一化坐标转换为像素坐标 for line in lines: parts line.strip().split() if len(parts) ! 5: continue class_id, cx, cy, bw, bh map(float, parts) # 反归一化中心点坐标和宽高都乘回原图尺寸 x_center int(cx * w) y_center int(cy * h) box_w int(bw * w) box_h int(bh * h) # 由中心点宽高推算出左上角和右下角 x_min max(0, int(x_center - box_w / 2)) y_min max(0, int(y_center - box_h / 2)) x_max min(w, int(x_center box_w / 2)) y_max min(h, int(y_center box_h / 2)) # 第四步画矩形框颜色用BGR格式线宽2 cv2.rectangle(img, (x_min, y_min), (x_max, y_max), (0, 0, 255), 2) cv2.imwrite(output_path, img) print(f可视化结果已保存: {output_path}) if __name__ __main__: # 常见做法随机取一张训练集图片来验证 image_path images/train/0780.jpg label_path labels/train/0780.txt visualize(image_path, label_path)这段代码里有几个容易忽略的细节。第一个是cv2.imread对中文路径不友好如果数据集解压路径带中文读取会直接返回None脚本干脆就不往下走了。第二个是坐标转换后的值要拿int()取整因为像素坐标必须是整数。第三个是画框前做了max和min的边界裁剪防止边框画出图片范围导致OpenCV报错。3.2 手动改图验证把脚本改成扫描整个目录数据集自带脚本通常写死了单张图片的路径但实际使用中我更建议你改成遍历整个验证集一次性把所有图都画出来这样能直观看到一批标注的整体质量import cv2 import os import glob image_dir images/val label_dir labels/val output_dir visual_check os.makedirs(output_dir, exist_okTrue) jpg_files glob.glob(os.path.join(image_dir, *.jpg)) for img_path in jpg_files: basename os.path.basename(img_path).replace(.jpg, .txt) label_path os.path.join(label_dir, basename) if not os.path.exists(label_path): print(f缺少标签文件: {basename}) continue img cv2.imread(img_path) if img is None: continue h, w img.shape[:2] with open(label_path, r, encodingutf-8) as f: lines f.readlines() for line in lines: parts line.strip().split() if len(parts) ! 5: continue _, cx, cy, bw, bh map(float, parts) x_min int((cx - bw / 2) * w) y_min int((cy - bh / 2) * h) x_max int((cx bw / 2) * w) y_max int((cy bh / 2) * h) cv2.rectangle(img, (x_min, y_min), (x_max, y_max), (0, 0, 255), 2) out_path os.path.join(output_dir, os.path.basename(img_path)) cv2.imwrite(out_path, img) print(f共处理 {len(jpg_files)} 张图片结果保存在 {output_dir}/)跑完这个脚本把visual_check目录里的图片快速翻一遍。重点看两类问题一是框的位置和缺陷实际位置是否吻合二是框的大小是否明显偏大或偏小。如果框普遍比缺陷大一圈说明标注时用了外接矩形且包含了多余背景如果框太小模型训练时学到的特征就不完整。3.3 可视化能帮你发现什么可视化不是为了看个热闹。它能直接暴露三类问题标签坐标越界、框位置偏移、类别混淆。比如一张图里缺陷明明在左下角框却画到了右上角那就是txt文件里坐标和图片内容对不上这种数据混入训练集会严重拉低mAP。我拿到任何数据集的第一步就是跑可视化这比看任何数据说明文档都直观。脚本能跑通、框画得准这份数据基本就没大问题如果画出来乱七八糟那份数据就算吹得再好也得留个心眼。4. 数据划分与YOLO训练前准备480/120背后的事4.1 train/val划分比例为什么是480和120这份数据集按8:2的比例划分训练集约480张验证集约120张。这个比例在目标检测领域很常见符合YOLO官方COCO数据集的划分习惯。8:2的好处在于训练数据足够学出defect的基本特征验证集也有120张评估出来的mAP指标不至于因为样本太少而波动太大。但有一点要明白480张训练图在小目标或密集场景下并不算多。绝缘子在输电线路图像里往往只占几十个像素如果缺陷目标本身就小模型容易漏检。所以这份数据更适合跑通流程、验证模型结构如果想部署到实际巡线场景通常还需要再加数据。数据划分这件事资源已经替你做了。但你要检查一件事images里的文件名和labels里的文件名是否严格一一对应。常见翻车是某些txt是空的——图片还在但标签文件里一行都没有YOLO训练时会把这张图跳过但你会看到“empty label”的警告。4.2 训练前的五项检查清单开始训练之前我一般会强制走一遍下面这个检查清单全部通过再开训。第一项统计标签数量。写个小脚本数一数所有txt文件的总行数确认有足够的正样本。如果defect目标总数低于几百个模型大概率欠拟合。第二项检查坐标范围。用前面2.2节的扫描代码跑一遍全部2500个txt文件确认没有越界值。坐标越界最典型的表现是训练loss输出了nan。第三项确认图片能正常读取。遍历所有jpg用cv2.imread验证返回的不是None顺便统计图片尺寸分布。YOLO会自动做letterbox缩放但极端长宽比还是会影响检测效果。第四项写好data.yaml。这份资源的摘要里没明确说是否自带data.yaml如果解压后没有需要自己创建# data.yaml path: /absolute/path/to/insulator_defect # 数据集绝对路径Windows下注意斜杠方向 train: images/train val: images/val nc: 1 names: [defect]第五项核对class编号。如果classes.txt里defect是第0个那标签txt里类别编号就应该是0data.yaml里names的顺序也必须对应。这三处只要有一处错位训练出来的模型类别就全是乱的。4.3 用yolov5训练这份数据的常见命令路径配置无误后训练命令并不复杂。在YOLOv5仓库目录下执行python train.py --data /path/to/insulator_defect/data.yaml --weights yolov5s.pt --batch-size 16 --epochs 100 --imgsz 640参数含义--data指向data.yaml--weights用yolov5s预训练权重做迁移学习--batch-size 16需要根据显存调整--imgsz 640是输入分辨率。如果显存只有6Gbatch-size降到8imgsz降到512。迁移学习的收敛速度比从头训练快得多100个epoch在单卡上大约跑半小时到一小时具体取决于显卡型号。5. 避坑指南标签、路径与数据质量的血泪经验5.1 坐标越界导致Loss变成NaN现象训练到某个epoch时loss突然输出nan训练直接中断或者指标全部变成无效值。原因标签txt里存在归一化坐标超出[0,1]区间的行。比如cx是1.2意味着目标中心点在图外或者w是0.8框宽占了整张图的80%以上明显不合理。训练时YOLO在前处理阶段对坐标做计算遇到越界值会产生无效梯度。解决用2.2节的扫描脚本跑一遍所有标签文件把越界的txt行打印出来逐条修正。修正方式是重新标注或者删除该行。我见过更隐蔽的情况——标注工具导出了未归一化的像素坐标直接当成归一化值写入txt这种数据只靠肉眼很难发现扫描脚本能直接抓出来。5.2 类别编号错位导致训练结果张冠李戴现象训练正常结束loss也收敛了但验证集上预测出来的类别和实际标注完全对不上。原因classes.txt定义了defect一个类编号为0。但部分标签文件的类别编号写成1或者data.yaml里names顺序写反了。三处不一致时模型学了错误的映射关系。解决解压后第一时间核对三处——classes.txt内容、所有标签txt的行首数字、data.yaml中的names顺序。三者必须完全一致。对于单类数据集行首数字应当全部是0。5.3 图片文件损坏或格式伪装成jpg现象训练时频繁报“image not found”或“corrupt JPEG”但文件管理器里能看到这个文件。原因下载传输中途文件损坏或者部分图片实际是PNG格式但后缀改成了.jpg。OpenCV读取这类文件时解析失败返回None。YOLO的dataloader遇到None会跳过或报错如果损坏文件数量多训练数据不足模型性能受影响。解决写一段遍历代码对每张图做cv2.imread并检查返回结果。损坏的图片直接删除或重新下载。值得注意的一个细节是有些标注工具读不了损坏图当时标注时就把这张图跳过了导致图片存在但标签缺失——这也是为什么第4章要检查一一对应。5.4 路径包含中文或空格导致读取失败现象Windows下训练报错找不到文件但路径确认无误可视化脚本也画不出图。原因cv2.imread和部分老版本PyTorch的ImageLoader对中文路径支持不完整。数据集放在D:\下载\绝缘子缺陷\这样的路径下文件读取直接失败。空格路径在Linux下没问题Windows下也可能引发意外。解决把数据集移动或重命名到纯英文路径下目录层级不要太深比如D:\dataset\insulator_defect。这个坑出现的频率远超想象尤其是从网盘下载后直接解压到“下载”文件夹的场景。5.5 可视化脚本保存图片乱码或画框偏移现象脚本能运行但输出的图片上汉字说明变成乱码或者框的位置偏向某一侧。原因乱码是matplotlib或OpenCV的putText默认字体不支持中文画框偏移则是反归一化时忘记乘以图片宽高或者代码里把x和y的顺序写反了。解决如果只是画框不写中文标注用cv2.rectangle就够不涉及字体问题。如果确实要在图上写字用cv2.putText并指定cv2.FONT_HERSHEY_SIMPLEX字体它只支持英文。画框偏移问题回头检查代码里cx乘以的是不是w、cy乘以的是不是h——这两个写反是可视化最常见的玄学bug。6. 从单类defect到多类扩展以及验证数据集质量的评估手段单类数据集的价值在于跑通流程真正要落地到巡检场景你大概率需要把defect细分。比如把标注拆成破损、自爆、污闪三个类别操作流程是把classes.txt改成三行用labelImg或X-AnyLabeling把每张图重新标注一遍然后重新划分训练验证集。扩展时注意一个原则新类别如果样本量少于50个检测效果基本不可用该考虑的就是采集数据而不是硬训。验证这份数据集能不能用除了跑可视化更硬核的手段是训练完成后看验证集的mAP0.5。单类检测任务里mAP0.5能到85%以上说明数据质量和数量都过得去如果只有60%出头第一优先排查的是标签错标和漏标而不是调网络结构。你可以把预测结果导出成txt和标注逐张对比看看漏检和误检分别集中在什么工况下。我自己的习惯是拿到任何一种数据集先跑一遍标签范围扫描再抽三张图做可视化确认最后才写data.yaml开训。这套流程花不了十分钟但能过滤掉一半以上的数据坑。从那以后我每次拿到新数据集都强制走这三步极少再在训练阶段翻车。希望帮到你。本文还有配套的精品资源点击获取