简介电力输电线路目标检测数据集.zip 是一套面向输电线路智能巡检与设备缺陷识别场景的工业级目标检测数据集。图片全部拍摄自真实工业现场共969张覆盖35类电力设备组件包括复合绝缘子、玻璃绝缘子、电缆接头、连接金具、支架装置等关键部件可支撑无人机巡检、变电站监控及电力设备维护等智能应用。资源包共1940个文件包含969张jpg图片、969个txt的YOLO格式标注文件、1个yaml数据集配置文件以及1个docx说明文档压缩包整体大小88.54MB结构清晰可直接导入YOLOv5/YOLOv8等主流框架开始训练。目前已有496人学习下载。数据集标注经领域专家校验边界框定位精确类别定义明确适合用于输电线路缺陷识别、组件状态异常预警、智能运维系统研发等方向对需要高质量电力行业标注数据的研究者或工程师是一个可以直接上手的实用资源。1. 输电线路目标检测数据集为什么一张 zip 压缩包能卡住整个巡检项目做输电线路巡检的同行应该都遇到过这种局面无人机或者直升机把可见光、红外影像一堆一堆地导回来算法团队急着要一份带标注的数据集来微调模型结果发现手里这份「电力输电线路目标检测数据集.zip」要么标注格式老旧要么类别定义和你自己的业务对不上要么解压之后发现图片尺寸、目标尺度分布跟实际场景根本不是一回事。真正让项目卡住的往往不是模型结构而是这份数据能不能顺利接进你的训练管线。这类数据集 zip 包通常是围绕绝缘子、防震锤、悬垂线夹、鸟巢、异物悬挂这几类高频巡检目标做的图片来源于实际巡线航拍带 XML 或 TXT 标注。它解决的场景很具体用 YOLO 系列做绝缘子缺损识别、用 Faster R-CNN 做小目标定位、或者用分割模型做线缆与背景分离。适合的读者不是刚学目标检测的入门者而是手里已经有训练脚本、正在为数据格式和类别映射头疼的工程人员。我围绕这份 zip 做了一整套落地路径从解压验货、标注格式转换、类别筛选到训练参数设置与踩坑排查全部按一线干活的方式来讲。读完你至少能判断这份数据集值不值得用、怎么改造成适合自己业务的格式以及哪些坑是这类航拍数据集共通的换个数据集也一样会遇到。2. 先看清压缩包里装的是什么数据验货与文件结构摸底2.1 解压之前先看目录树别急着双击解压很多人拿到 zip 的第一反应是右键解压然后丢进训练脚本里跑。这个动作在别的数据集上可能没问题但输电线路数据集往往存在三个隐患一是压缩包内层还有一层目录解压后路径嵌套不一致导致 DataLoader 读不到图片二是图片命名可能带中文或者特殊字符Windows 和 Linux 下的表现不一致三是标注文件可能与图片不在同一个根目录下有的包把 JPEG 和 XML 分开放。我一般的做法是先用命令行看一眼压缩包内部的目录结构不解压也能知道大概布局。在 Linux 下可以直接用 unzip -lWindows 下可以用 tar 命令Win10 1803 之后自带或者直接用 7-Zip 的列表功能。# 查看 zip 内部完整路径不解压 unzip -l 电力输电线路目标检测数据集.zip | head -50 # 统计图片和标注文件数量确认类别文件是否存在 unzip -l 电力输电线路目标检测数据集.zip | grep -E \.(jpg|jpeg|png)$ | wc -l unzip -l 电力输电线路目标检测数据集.zip | grep -E \.(xml|txt)$ | wc -l这段命令的作用是快速摸底第一行看路径结构确认是否有内层嵌套第二行统计图片数量第三行统计标注数量。如果图片数和标注数对不上说明有部分图片没标或者标注文件命名不匹配这类脏数据在后续训练中会直接报 FileNotFoundError 或者被数据加载器静默跳过属于比较隐蔽的坑。提示如果 unzip 命令不存在Debian/Ubuntu 系安装 unzipCentOS 系用 yum install unzip。Windows 下建议用 PowerShell 的 Expand-Archive 或者 7-Zip 命令行版尽量避免用系统自带资源管理器解压因为它在处理长路径和中文文件名时更容易出问题。2.2 标注格式识别XML、TXT 还是 JSON输电线路数据集的标注格式通常和来源平台强相关。如果是基于 labelImg 标注的大概率是 PASCAL VOC 的 XML 格式如果是基于 labelme 标注的是 JSON 格式如果是从某个检测平台导出的可能是 YOLO 的 TXT 格式。在动手写转换脚本之前先随机抽几个文件看看内容这一步能省下后面大量的调试时间。# 解压到指定目录 unzip 电力输电线路目标检测数据集.zip -d transmission_line_data # 抽查一个标注文件的前 20 行 find transmission_line_data -name *.xml | head -1 | xargs head -20 find transmission_line_data -name *.txt | head -1 | xargs head -20XML 标注里通常会有object节点包含name和bndbox坐标YOLO TXT 标注的第一列是类别编号后面四列是归一化的中心点 x、中心点 y、宽、高JSON 标注则会有shapes列表。判断出格式之后才能决定下一步是直接训练还是要做转换。这里有一个常见的分歧点很多输电线路数据集里的 XML 命名空间并不是标准的 PASCAL VOC 结构有的多了segmented字段有的folder写的是原始采集路径还有的path指向的是标注机的本地绝对路径。这些字段不影响训练但会影响你自己的数据检查脚本所以抽看时要重点关注name和bndbox这两个核心字段是否完整。2.3 类别定义表这是决定数据集值不值得用的核心打开标注文件看类别名称比看任何说明文档都重要。同一类目标在不同数据集里可能叫法完全不同绝缘子可能是insulator、insulator_damage、porcelain_insulator防震锤可能是hammer、damper、stockbridge_damper鸟巢可能是bird_nest、nest、birdnest。如果你的业务只关注绝缘子缺陷但数据集里把绝缘子和缺陷分成两个类别训练目标和实际需求就对不上了。我建议把所有标注里出现过的类别名统计出来再对照业务需求做映射。这一步不要靠肉眼翻文件写几行命令直接统计。# 统计 XML 格式中出现的所有类别名称 grep -h name transmission_line_data -r | sed s/.*name\(.*\)\/name.*/\1/ | sort | uniq -c | sort -nr # 统计 YOLO TXT 格式中出现的类别编号 find transmission_line_data -name *.txt -exec cat {} | awk {print $1} | sort | uniq -c如果统计结果里出现 20 多个类别而其中大部分跟你的业务无关这种数据集直接拿来训练反而会拉低精度。更合理的做法是只保留需要的类别把其他类别的标注从图片和标注文件中剔除。这个操作放在格式转换阶段一起做效率更高。3. 把 VOC 转成 YOLO 格式转换脚本与四个边界坑3.1 为什么必须转 YOLO 格式输电线路目标检测目前的主流落地路径就是 YOLO 系列从 YOLOv5 到 YOLOv8 再到最新的 YOLO11官方训练脚本默认吃的是 YOLO TXT 格式每张图片对应一个同名 txt每行一个目标格式为「类别编号 中心点x 中心点y 宽度 高度」坐标全部归一化到 01 之间。VOC 的 XML 格式记录的是绝对像素坐标的左上角和右下角两个格式之间差着一层数学换算不能直接替换。有人会问YOLO 能不能直接读 XML答案是不能官方仓库的训练脚本没有内置 XML 解析器。Ultralytics 的 YOLOv8 支持的数据集标注格式确实有几种但 TXT 依然是最稳妥的。与其改训练脚本不如把标注转成 TXT这也符合大多数开源项目的数据组织方式。3.2 转换脚本一张表固化类别映射写转换脚本时第一件事是建立类别映射表。这个映射表必须稳定因为训练时的类别顺序和数据集的类别顺序如果不一致模型输出的类别编号就全错了等于白训练。下面这个 Python 脚本实现 XML 到 YOLO TXT 的转换把类别映射放在脚本顶部的字典里方便直接复制修改。import os import xml.etree.ElementTree as ET from pathlib import Path # 类别映射源类别名 - 目标类别编号 CATEGORY_MAP { insulator: 0, insulator_damage: 1, damper: 2, bird_nest: 3 } # 如果要忽略某些类别直接不写进映射表即可 def convert_xml_to_yolo(xml_path, output_dir, image_width, image_height): tree ET.parse(xml_path) root tree.getroot() # 优先读取 XML 里标注的图片尺寸读不到再回退到传入参数 size root.find(size) if size is not None and size.find(width) is not None: image_width int(size.find(width).text) image_height int(size.find(height).text) lines [] for obj in root.findall(object): name obj.find(name).text if name not in CATEGORY_MAP: continue # 跳过不需要的类别 bndbox obj.find(bndbox) xmin float(bndbox.find(xmin).text) ymin float(bndbox.find(ymin).text) xmax float(bndbox.find(xmax).text) ymax float(bndbox.find(ymax).text) # VOC 坐标是左上角右下角YOLO 需要中心点和宽高 x_center (xmin xmax) / 2.0 / image_width y_center (ymin ymax) / 2.0 / image_height width (xmax - xmin) / image_width height (ymax - ymin) / image_height # 坐标必须归一化到 0~1负数和大于 1 的数值要裁剪 x_center max(0.0, min(1.0, x_center)) y_center max(0.0, min(1.0, y_center)) width max(0.0, min(1.0, width)) height max(0.0, min(1.0, height)) lines.append(f{CATEGORY_MAP[name]} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) # 输出文件名必须和图片名保持一致扩展名换成 txt output_path Path(output_dir) / (Path(xml_path).stem .txt) with open(output_path, w) as f: f.write(\n.join(lines))这段脚本的逻辑很直白遍历 XML 的每个object取出类别名和真实坐标框通过映射表转换成类别编号坐标从左上角右下角转成中心点加宽高并归一化最后写入同名 txt。写完后我用一段循环来批量处理整个目录并打印每张图的标注数量方便核对。批量处理时要注意一个细节脚本里读取 XML 自带的size字段是优先方式但如果数据集的 XML 里size写的是 0 或者缺失就一定要从图片本身读取宽高否则坐标全部算错而且错得非常隐蔽——训练 loss 可能还会下降但验证精度始终起不来。我一般会在转换前写一个小脚本对每个 XML 检查size字段是否有效无效的单独列出。from PIL import Image import xml.etree.ElementTree as ET # 对转换后的 txt 做反向验证把 YOLO 坐标乘以宽高转回像素坐标检查是否越界 img Image.open(example.jpg) w, h img.size with open(example.txt) as f: for line in f: cls, xc, yc, bw, bh line.split() x1 (float(xc) - float(bw) / 2) * w y1 (float(yc) - float(bh) / 2) * h x2 (float(xc) float(bw) / 2) * w y2 (float(yc) float(bh) / 2) * h print(fclass{cls}, box({x1:.1f}, {y1:.1f}) - ({x2:.1f}, {y2:.1f}))3.3 归一化坐标的精度取舍YOLO TXT 里的坐标是浮点数常见精度是六位小数。六位小数在 4000×3000 的航拍大图上对应的像素误差大约 0.04 像素左右完全够用但有些标注工具导出的是小数点后两位数这个精度在训练的时候会导致框的抖动因为同一个框在不同 epoch 读取时浮点换算会有细微差异。转换时建议固定保留六位既保持精度又不至于让文件过大。还有一个容易被忽略的细节坐标值可能刚好落在图片边界之外尤其是目标被截断时VOC 的 xmax 可能大于图片宽度。YOLO 训练时如果读到大于 1 的归一化坐标虽然不报错但会在损失计算时产生异常梯度。所以转换时做裁剪是必要的上面的脚本已经包含了这一步。3.4 四个边界坑位逐一对应第一个坑是 XML 里size字段与实际图片尺寸不一致。有的数据集在标注时图片被缩放或裁剪过但 XML 没有同步更新。解决方法是转换时直接读图片宽高替代 XML 字段代价是速度慢一点但准确性优先。第二个坑是类别名带空格或大小写不一致。比如Insulator和insulator同时存在在统计类别时会被当成两个类转换时映射不到就直接跳过导致部分标注丢失。建议在转换前统一做一次小写化和去空格处理把脏数据挡在训练管线之外。第三个坑是数据集里混有全景大图和裁切小图。航拍数据里常见一张 4000×3000 的图上只有一个小绝缘子另一张 640×480 的图上绝缘子占了半幅。这两种图混在一起训练模型对大目标的过拟合和对小目标的欠拟合会同时发生。处理方式是先统计所有标注框的面积分布面积占比差异超过一个数量级的建议分开训练或者做尺度归一化。第四个坑是标注框为 0 的图片。XML 里如果没有object转换出来的 txt 是空文件。Ultralytics 的训练脚本对空标注文件是容忍的但验证的时候 mAP 计算会被这类图片拉低。我一般会把空标注的图片单独挪到一个子集不作为训练数据而是作为负样本在测试阶段验证误检率。4. 构建训练集与验证集目录组织与数据集配置文件4.1 70/20/10 划分还是按塔杆划分输电线路数据和通用目标检测数据有一个重要区别同一基塔的多个视角图片之间高度相似如果划分训练集和验证集时按图片随机划分大概率会造成数据泄漏也就是同一基塔的画面同时出现在训练集和验证集里验证结果虚高实际部署时精度下降明显。正确的划分方式是按塔杆或者按航线划分。如果数据集的文件名里带有塔杆编号优先按塔杆分组后划分如果没有退而求其次按文件夹划分。常见的比例是训练集 70%、验证集 20%、测试集 10%但我会在实际操作中把验证集比例稍微提高因为输电线路场景的类别不平衡问题严重验证集太小的话某些类别一个目标都没有mAP 计算不稳定。4.2 标准 YOLO 数据集目录结构与 data.yamlUltralytics 的 YOLO 训练脚本要求数据集目录遵循固定结构images 和 labels 两个主目录分别存放所有图片和所有 txt 标注txt 和图片保持同名训练集、验证集、测试集通过 data.yaml 里的路径来指定而不是通过不同文件夹区分。# transmission_line.yaml path: D:/datasets/transmission_line_2024 # 数据集根目录 train: images/train val: images/val test: images/test # 类别定义 names: 0: insulator 1: insulator_damage 2: damper 3: bird_nest这里必须注意的是names的顺序必须和转换脚本里的CATEGORY_MAP编号完全一致否则模型训练时学到的类别编号和推理时输出的含义对不上。很多人训练完模型之后发现推理结果类别错乱90% 的问题出在这个映射关系上而不是模型本身。如果你的数据量不大我建议把path写成绝对路径避免相对路径带来的各种诡异问题。跨机器拷贝项目时绝对路径当然会失效但这属于搬运时的已知成本训练前的稳定性更重要。4.3 按类别数量过滤无效图片输电线路数据集里的类别分布往往极端不均衡绝缘子可能有几万个框鸟巢可能只有几百个。这里有一个两难如果按原始分布训练模型对少数类几乎学不到特征如果对少数类做过采样又容易过拟合。我一般的处理思路分两步第一步先统计每个类别的目标数量打印出来人工判断第二步对每个类别设定一个最低目标数低于这个阈值的类别从训练目标里暂时剔除等后续补充数据后再加回来。为什么不是用数据增强硬撑因为鸟巢、防震锤这类目标在航拍尺度下特征本来就弱靠翻转、旋转这类通用增强很难本质性提升不如先保证模型在主要类别上的精度。import os from collections import Counter # 统计训练集所有 txt 的类别分布 label_dir transmission_line_data/labels/train counter Counter() total_boxes 0 for txt_file in os.listdir(label_dir): if not txt_file.endswith(.txt): continue with open(os.path.join(label_dir, txt_file)) as f: for line in f: cls int(line.split()[0]) counter[cls] 1 total_boxes 1 for cls_id, count in sorted(counter.items()): print(fclass {cls_id}: {count} boxes ({count / total_boxes * 100:.2f}%))运行这段脚本后你就能对数据集的类别分布有直观认知。如果某个类别的占比低于 1%我的习惯是把这个类别的标注直接从训练标签中过滤掉保留在原始数据文件夹里不动等以后数据多了再重新切分。5. YOLO 训练参数设置与典型避坑案例5.1 输入尺寸、batch size 和 epoch 怎么定输电线路航拍图常见的分辨率是 4000×3000 甚至更高直接喂进 YOLO 不现实训练前会做 letterbox 缩放。这里有一个关键经验输入尺寸不能一味追求大因为航拍图中的目标普遍偏小如果输入尺寸太小绝缘子在 640×640 的图上可能只有十几个像素。我采用的参数组合是输入尺寸设为 1280batch size 为 8如果显存允许上调到 16epoch 为 100 起步。1280 这个尺寸在 YOLOv8 系列的默认配置里属于偏大的档位但对航拍小目标而言是必要的。如果显存有限优先保证输入尺寸而不是 batch size因为小目标检测对输入分辨率更敏感。训练时开启--workers 8提高数据加载并行度但 Windows 上数值调太低会导致 CPU 瓶颈。# YOLOv8 训练命令示例 yolo detect train \ datatransmission_line.yaml \ modelyolov8s.pt \ imgsz1280 \ batch8 \ epochs100 \ workers8 \ device0这里用 yolov8s 而不是更大的 yolov8l是因为输电线路目标类别少s 模型在推理速度和精度上更平衡。如果数据集只有 3000 张图l 模型几乎必然过拟合s 模型还能勉强压住。5.2 预训练权重选 YOLO 官方 COCO 还是业务权重迁移学习已经是目标检测训练的标配YOLO 系列默认会下载 COCO 预训练权重。COCO 权重包含的类别虽然与输电线路无关但浅层特征边缘、纹理、颜色是通用的对绝缘子这类人造物体同样有效。有一种更优的做法如果之前已经训练过一个输电线路模型直接用上一次的 best.pt 作为当前训练的初始权重收敛速度和最终精度都会更好。但这一步有一个风险如果新数据集的类别编号和旧模型不一致模型的输出层需要重新适配此时建议冻结前 10 层再解冻否则容易在训练早期出现大幅度波动。5.3 常见问题排查loss 不降、mAP 为 0、类别乱第一条踩坑记录训练了 20 个 epochloss 一直在 2 左右几乎不动。原因是学习率设置不当YOLOv8 默认的学习率对陌生数据集有时偏高或偏低。解决方法是先用默认参数跑 10 个 epoch 观察 loss 走势如果 loss 完全不变把学习率从 0.01 降到 0.001 再试如果 loss 剧烈震荡降到 0.0001。第二条踩坑记录验证集 mAP 始终为 0.0训练 loss 正常下降。排查发现是验证集路径错误data.yaml 里 val 路径指向了空目录YOLO 没有报错但验证集为零。解决方法是训练前手动检查 val 目录下图片数量和标注数量确保大于零。第三条踩坑记录模型推理时输出的类别编号和预设类别对不上。原因是转换脚本的CATEGORY_MAP和训练配置文件 data.yaml 里的names顺序不一致多了一个类别或少了一个类别。解决方法是统一从一个映射表生成两套配置而不是分别手改。第四条踩坑记录某些图片训练时报错提示标注坐标越界如 x 大于 1。原因是转换时没有做坐标裁剪部分标注框超出图片边界。解决方法是把所有 txt 再跑一遍坐标合法性检查遇到越界坐标要么裁剪要么把该图片剔除。第五条踩坑记录训练速度越来越慢数据加载成为瓶颈。原因是在 Windows 上 workers 设置太高导致频繁进程切换。解决方法是把 workers 调到 0 或 2优先保证稳定而不是纯粹的速度。5.4 验证集结果解读P、R、mAP50 与 mAP50-95 的区别训练结束后模型会输出一组验证指标。对于输电线路场景我强烈建议重点关注 mAP50 而不是 mAP50-95。原因是输电线路目标存在大量被遮挡或截断的情况mAP50-95 对框的精确度要求过于苛刻mAP50 更能反映实际效果。部署时我会以 mAP50 达到 0.8 以上作为合格线如果低于这个值优先返工数据处理而不是换模型结构。6. 模型推理验证与部署层面的翻车预防6.1 用小样本测试图快速验证模型行为训练完成之后不要急着封装成服务。先找三张最有代表性的测试图一张是目标完整清晰的一张是目标被树木遮挡的一张是完全没有目标的负样本。用这三张图推理能快速判断模型最基本的三个问题目标能不能检出来、遮挡情况下会不会漏检、对背景会不会误检。如果这三张都通过再扩展到整个测试集做统计评估。from ultralytics import YOLO # 加载训练好的权重 model YOLO(runs/detect/train/weights/best.pt) # 对单张图片做推理并保存结果 results model.predict( sourcetest_negative.jpg, # 测试图路径 conf0.25, # 置信度阈值 imgsz1280, # 必须与训练时一致 saveTrue, projectinfer_check, namenegative ) # 查看检测结果数量负样本上如果出现框说明误检严重 print(len(results[0].boxes))推理时最容易翻车的点是imgsz与训练不一致导致小目标尺度失配。用户往往训练用 1280推理时为了速度改成 640结果感觉模型变笨了其实是输入分辨率变了。如果推理端确实需要降分辨率至少要在训练时做多尺度训练--multi-scale否则部署精度会明显下降。6.2 输出坐标还原到原始大图的换算方式推理输出的坐标是相对输入图的如果输入经过了 letterbox 缩放坐标还需要还原到原始航拍图分辨率。YOLOv8 的 predict 结果里会附带orig_shape和boxes.xyxy前者的坐标是归一化后的乘以原始宽高即可得到原始像素坐标。但要注意 letterbox 填充的灰边会影响坐标映射建议直接使用results[0].boxes.xyxy配合原始图像尺寸做换算不要自己手动拼接。6.3 ONNX 导出与业务系统集成建议训练好的 PyTorch 模型直接部署在服务器上有两个问题依赖环境重、推理速度不理想。常见的做法是导出为 ONNX再通过 ONNX Runtime 或 TensorRT 执行推理这样能脱离 PyTorch 环境部署机器只需要装 ONNX Runtime大小只有几十 MB。# 导出 ONNX 格式 yolo export modelruns/detect/train/weights/best.pt formatonnx imgsz1280导出时有一个坑imgsz参数必须与训练尺寸一致否则导出的模型输入尺寸是默认的 640推理时虽然可以动态输入但精度会受影响。如果部署端确定只用 640 分辨率那就用 640 重新训练一个模型不要用 1280 训练好的模型硬转 640。我在实际项目里吃过一次亏模型训练用 1280导出 ONNX 时忘了加imgsz参数默认导出 640然后直接部署现场识别率掉了 15 个百分点。查了大半天才发现是输入尺寸不一致。后来把导出命令里的imgsz1280固定写进部署脚本再没出过这个问题。6.4 数据集追加更新时的增量训练策略输电线路模型不会只训一次。新的巡检任务会带来新图片和新缺陷样本此时不要重新从零训练也不要直接在 old 权重上继续不加区别地训练。增量训练的正确做法是把新老数据混合后重新划分数据集用旧模型的 best.pt 作为初始权重并将 epoch 减小到 3050学习率调低 10 倍防止灾难性遗忘。如果你发现增量训练后新类别效果好但老类别精度明显下降大概率是学习率太大或训练集不均衡。这时候应该给老类别额外复制几份以保证比例而不是简单调低学习率。这套流程我反复用过多次从一个 3000 张的数据集扩张到 8000 张模型精度是稳定上升的。希望这篇基于「电力输电线路目标检测数据集.zip」的完整落地经验能帮到你。数据到手之后先别急着跑花半天做格式校验和类别映射比训练完再返工省一周时间。本文还有配套的精品资源点击获取