简介本资源为输电线异物检测数据集面向电力巡检、无人机视觉检测方向的算法工程师与高校研究者用于训练和验证balloon、kite、nest、trash四类异物目标检测模型。压缩包共2000个文件包含1300张jpg图片及一一对应的1300个VOC格式xml标注文件和700个YOLO格式txt标注文件整体约831.71MB采用7z压缩兼容Pascal VOC与YOLO两种主流训练流程。标注由labelImg完成均以矩形框方式绘制四类框数分别为balloon 160、kite 181、nest 871、trash 107总框数1319其中约15%的样本经过数据增强可提升模型对复杂背景的适应能力。目前已有971人学习下载适合直接用于目标检测训练、类别分布分析与数据增强策略验证也可作为电力巡检场景下异物识别研究的基线数据参考。1. 输电线异物检测数据集1300 张 VOCYOLO 双格式到底能干什么输电线异物检测数据集 VOCYOLO 格式 1300 张 4 类别这个标题拆开看就三件事数据规模、标注格式、检测目标。1300 张图在目标检测里属于小数据集但放在输电线异物这个垂直场景里它够用——因为异物类别本身视觉特征集中不需要 ImageNet 那种百万级体量去学通用特征。VOC 和 YOLO 双格式意味着你拿到手就能直接喂给 YOLOv5/v8/v11 系列训练不用再折腾格式转换。4 个类别通常对应风筝、塑料袋、鸟巢、气球这类高空飘挂物具体类别名以数据集内 classes.txt 为准。这个数据集适合谁做电力巡检 AI 落地的算法工程师、想跑通 YOLO 训练全流程的入门者、以及需要快速验证检测方案可行性的项目组。它解决的核心问题是你不需要从零标注几千张输电线图像直接拿现成标注做 baseline把精力放在模型选型和部署优化上。1300 张的体量单卡 8G 显存就能跑完一轮完整训练这是它最大的实用价值。2. VOC 与 YOLO 双格式拆解标注文件到底长什么样2.1 VOC 格式的 XML 结构与字段含义VOC 格式每张图对应一个 XML 文件文件名与图片同名。核心字段就几个folder记录图片所在目录filename是图片文件名size下面分width、height、depth三个子标签object可以有多个每个object里name是类别名bndbox里xmin、ymin、xmax、ymax是左上角和右下角坐标坐标原点在图片左上角单位是像素。annotation folderimages/folder filename000001.jpg/filename size width1920/width height1080/height depth3/depth /size object namekite/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin342/xmin ymin156/ymin xmax578/xmax ymax389/ymax /bndbox /object /annotation这段 XML 里difficult字段容易被忽略。VOC 标准里difficult1表示该目标难以识别评估时通常跳过。输电线异物场景下如果标注者把被电线部分遮挡的异物标为 difficult你在训练时可以选择忽略这些样本避免模型学到模糊边界。truncated1表示目标被图片边缘截断这类样本在输电线巡检图里很常见——异物飘到画面边缘只露出一半。2.2 YOLO 格式的 txt 归一化坐标YOLO 格式每张图对应一个 txt 文件每行一个目标格式是class_id x_center y_center width height全部归一化到 0~1 之间。class_id 从 0 开始对应类别列表的索引。0 0.2396 0.2523 0.1229 0.2157 2 0.5671 0.4832 0.0893 0.1104第一行表示类别 0中心点横坐标是图片宽度的 23.96%纵坐标是高度的 25.23%框宽占图片宽度的 12.29%框高占高度的 21.57%。这种归一化设计让 YOLO 训练时不受输入分辨率影响你可以在训练配置里随意改imgsz标注不用动。2.3 两种格式的转换脚本与边界处理拿到 VOC 格式想转 YOLO核心就是坐标变换加归一化。下面这个脚本处理单目录下的所有 XML输出到指定文件夹。import xml.etree.ElementTree as ET import os def voc_to_yolo(xml_dir, out_dir, classes): os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(xml_dir, xml_file)) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) lines [] for obj in root.iter(object): # 跳过 difficult 目标按需开启 # if obj.find(difficult).text 1: # continue cls_name obj.find(name).text if cls_name not in classes: continue cls_id classes.index(cls_name) bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 裁剪越界坐标 xmin max(0, min(xmin, w)) xmax max(0, min(xmax, w)) ymin max(0, min(ymin, h)) ymax max(0, min(ymax, h)) x_center (xmin xmax) / 2.0 / w y_center (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {bw:.6f} {bh:.6f}) out_path os.path.join(out_dir, xml_file.replace(.xml, .txt)) with open(out_path, w) as f: f.write(\n.join(lines)) classes [kite, plastic_bag, bird_nest, balloon] voc_to_yolo(./annotations, ./labels, classes)classes列表顺序必须和数据集提供的类别定义一致否则 class_id 全错。坐标裁剪那两行是血泪经验——有些 XML 里 xmax 会超出图片宽度不裁剪的话归一化后大于 1YOLO 训练时直接报错。difficult跳过逻辑默认注释掉因为输电线异物本身样本就少跳过 difficult 可能让某些类别样本量不够。注意转换后务必抽查几张图的 txt用可视化脚本画框确认坐标没偏。我见过有人转换后没检查训练 loss 正常下降但 mAP 极低最后发现是 xmin 和 xmax 写反了。3. 用 YOLOv8 跑通训练从数据配置到第一轮结果3.1 数据集目录组织与 data.yaml 写法YOLOv8 要求的数据集结构很固定根目录下分images和labels各自再分train、val、test。图片和标注文件同名不同后缀放在对应子目录里。dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yamldata.yaml内容如下path: /home/user/dataset train: images/train val: images/val test: images/test nc: 4 names: [kite, plastic_bag, bird_nest, balloon]nc是类别数必须和 names 长度一致。path写绝对路径最稳相对路径在不同工作目录下容易翻车。1300 张按 8:1:1 划分训练集 1040 张验证集和测试集各 130 张。如果某些类别样本特别少划分时要做分层抽样保证每个子集里都有四个类别。3.2 训练命令与关键参数设置yolo detect train \ datadataset/data.yaml \ modelyolov8n.pt \ epochs200 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ patience50 \ device0 \ projectruns/train \ nameexp1modelyolov8n.pt用 nano 版本起步1300 张数据量下 nano 足够参数量小、训练快。imgsz640是 YOLO 系列的标准输入尺寸输电线异物在 640 分辨率下如果目标小于 16x16 像素考虑提到 1280但显存占用翻倍。batch16在 8G 显存下跑 640 分辨率刚好显存不够就降到 8 或 4。lr00.01是初始学习率小数据集建议降到 0.001 避免震荡。patience50表示 50 轮验证指标不提升就早停防止过拟合。训练过程中重点看三个指标box_loss是否稳定下降、mAP50是否持续上升、cls_loss是否收敛。如果 box_loss 下降但 mAP50 不涨大概率是标注质量问题如果 cls_loss 震荡检查类别是否混淆。3.3 推理验证与结果解读yolo detect predict \ modelruns/train/exp1/weights/best.pt \ sourcedataset/images/test \ conf0.25 \ iou0.45 \ saveTrueconf0.25是置信度阈值低于这个值的检测框被过滤。输电线异物检测场景下漏检比误检代价高可以降到 0.15 提高召回。iou0.45是 NMS 的 IoU 阈值两个框重叠超过 45% 就保留置信度高的那个。如果同类异物密集出现IoU 调高到 0.6 避免误抑制。推理结果在runs/detect/predict下每张图会画出检测框和类别标签。重点看漏检和误检漏检的异物通常是小目标或被遮挡误检多半是把电线交叉点、绝缘子当成异物。把误检样本挑出来加进训练集做一轮增量训练mAP 通常能涨 3~5 个点。4. 输电线异物检测的避坑清单标注、训练、部署各踩一遍4.1 标注框贴边导致训练不稳定现象训练前期 loss 正常下降到 50 轮左右突然飙升之后震荡不收敛。原因部分标注框的 xmin/ymin 等于 0 或 xmax/ymax 等于图片宽高归一化后坐标正好是 0 或 1。YOLO 在计算损失时对边界值敏感梯度容易爆炸。解决转换脚本里加裁剪逻辑把坐标限制在[1, w-1]和[1, h-1]范围内。或者训练时开rectTrue做矩形推理减少 padding 带来的边界效应。4.2 类别不平衡导致小类漏检严重现象四个类别里鸟巢和气球检测效果很好风筝和塑料袋 mAP 只有 0.3 左右。原因1300 张图里风筝和塑料袋的标注框数量可能只有鸟巢的三分之一。YOLO 默认损失函数对类别不平衡没有特殊处理小类梯度被大类淹没。解决在data.yaml同级目录建一个hyp.yaml调cls_pw1.0给类别损失加权或者用copy_paste数据增强给小类做过采样。更直接的办法是训练时用fraction0.8只取部分数据但手动保证每个 batch 里小类样本占比不低于 20%。4.3 验证集 mAP 高但实际推理漏检现象验证集 mAP50 到 0.85拿现场巡检图推理漏检率超过 40%。原因训练集和验证集来自同一批数据分布一致。现场图的光照、角度、背景和训练集差异大模型过拟合了训练集的纹理特征。解决划分验证集时按拍摄日期或拍摄设备分不要随机分。训练时加hsv_h0.015、hsv_s0.7、hsv_v0.4做颜色增强加degrees10做小角度旋转提升泛化。如果现场图能拿到哪怕只有几十张也加进训练集做微调。4.4 推理速度不达标导致无法实时现象YOLOv8n 在 640 分辨率下用 PyTorch 推理单张图 30ms但业务要求 25fps 实时处理。原因PyTorch 默认推理没做图优化算子融合和半精度都没开。解决导出 ONNX 或 TensorRT 引擎。yolo export modelbest.pt formatengine halfTrue导出 TensorRT FP16 引擎推理速度通常能降到 8~12ms。如果还不行降到 416 分辨率或者换 yolov8n 的剪枝版本。4.5 双格式数据集混用导致标签错位现象用 VOC 格式的 XML 转完 YOLO 后训练时发现某些图的框位置完全不对像是偏移了半个图片。原因VOC 的坐标原点在左上角但有些标注工具导出时用了左下角原点或者图片被旋转过但 XML 没更新尺寸。解决转换前先用脚本批量检查 XML 里的size和实际图片尺寸是否一致。不一致的要么重新标注要么用 PIL 读图后按实际尺寸重新归一化。转换后随机抽 20 张画框可视化确认框和异物对齐。5. 小数据集提点技巧从 1300 张里榨出更高 mAP5.1 用预训练权重做冻结训练再解冻1300 张直接从头训容易过拟合。我一般分两阶段前 50 轮冻结 backbone只训 head学习率设 0.01后 150 轮解冻全部层学习率降到 0.001。YOLOv8 里用freeze10冻结前 10 层训练完再跑一次freeze0的微调。# 第一阶段冻结 backbone yolo detect train datadataset/data.yaml modelyolov8n.pt epochs50 freeze10 lr00.01 # 第二阶段解冻微调 yolo detect train datadataset/data.yaml modelruns/train/exp/weights/last.pt epochs150 lr00.001冻结训练让 head 先适应输电线异物的特征分布解冻后 backbone 再微调比直接端到端训练收敛更稳。实测 mAP50 能比直接训高 4~6 个点。5.2 用 SAHI 切片推理抓小目标输电线异物在 1920x1080 原图里可能只占 30x30 像素缩到 640 后只剩 10x10YOLO 的 stride 32 特征图根本覆盖不到。SAHISlicing Aided Hyper Inference把原图切成重叠的小块分别推理再合并结果。from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction model AutoDetectionModel.from_pretrained( model_typeyolov8, model_pathruns/train/exp/weights/best.pt, confidence_threshold0.2, devicecuda:0 ) result get_sliced_prediction( test_image.jpg, model, slice_height640, slice_width640, overlap_height_ratio0.2, overlap_width_ratio0.2 ) result.export_visuals(export_dirsahi_output/)slice_height和slice_width设 640和训练分辨率一致。overlap_ratio0.2保证切片边缘的目标至少完整出现在一个切片里。SAHI 的代价是推理时间翻 4~6 倍适合离线巡检图分析不适合实时视频流。5.3 用 TTA 和模型集成做最后冲刺如果 mAP 卡在 0.8 上不去开 TTATest Time Augmentation。YOLO 推理时加augmentTrue对每张图做翻转、缩放多尺度推理结果取平均。yolo detect predict modelbest.pt sourcetest_images augmentTrue conf0.2TTA 通常能涨 1~2 个点但推理时间翻 3 倍。另一个办法是训三个不同 seed 的模型做加权框融合WBF比 NMS 保留更多候选框小目标召回提升明显。WBF 用ensemble-boxes库实现三个模型的权重按验证集 mAP 分配。5.4 一个容易被忽略的细节验证集阈值调优YOLO 默认用 conf0.001 跑验证集算 mAP但实际部署时 conf 设 0.25。这两个阈值下的 mAP 可能差 5 个点。我习惯在验证集上跑一遍 conf 从 0.05 到 0.5 的扫描画 P-R 曲线找 F1 最高的点作为部署阈值。输电线异物检测漏检代价高我会把阈值往左偏宁可多误检几个也不漏。from ultralytics import YOLO model YOLO(best.pt) metrics model.val(datadata.yaml, conf0.15, iou0.5) print(metrics.box.map50, metrics.box.map)这个习惯帮我省过好几次事——有一次验证集 mAP50 0.82但 conf0.25 时实际召回只有 0.65调到 0.12 后召回上到 0.81误检只多了 3%。阈值这东西别用默认值自己扫一遍。希望帮到你。本文还有配套的精品资源点击获取