拓冰建站拓冰建站
首页 / 资讯中心 / 正文

输电线路螺栓销钉缺失检测:1209张VOC大目标图像数据集实战

简介面向输电线路智能巡检场景的目标检测数据集聚焦螺栓销钉缺失这一细小缺陷的自动识别问题适合计算机视觉初学者与电力运维算法开发者用于模型训练、算法对比及工程落地验证。数据集共1209张输电线路高清图像压缩包内含2000个文件以791张JPG原图和1209个XML标注文件为主标注遵循PASCAL VOC标准使用labelimg工具生成边界框与类别标签类别划分为“正常”和“销钉缺失”两种状态可为基于YOLOv7等主流框架的缺陷检测提供直接训练语料。包体整体89.52MB大小适中便于下载和快速迭代当前已有1199人浏览学习。借助这套数据可训练出平均精度mAP达93.7%的检测模型帮助运维人员自动定位销钉缺失风险减少人工登塔巡检的频次与安全隐患同时为输电线路缺陷检测方向的研究提供标准化数据支撑从数据标注、模型训练到效果评估均有较高参考价值。1. 输电线路螺栓销钉缺失检测图像数据集1209张图能把误检率打下来多少无人机巡检拍回来的塔材照片一张张放大找销钉眼睛一小时就花了还容易漏。这个输电线路螺栓销钉缺失检测图像数据集就是冲着这个场景去的1209张图像统一VOC标注目标尺寸偏大不做小目标检测那套花活专门解决“塔材上那颗销钉到底还在不在”的二分类问题。对做电力巡检视觉方案的人来说它最大的价值不是数量而是“大目标”这个属性——意味着用轻量模型就能跑出可用精度也意味着数据增强和锚框策略跟常规工业检测不一样。下面从标注格式讲起把解析、训练、避坑一条线走完。2. VOC标注不只是改个扩展名拆解1209张图的类别分布与目标尺度2.1 JPEGImages与Annotations先跑一段代码把家底摸清拿到数据集第一件事不是开训练而是写脚本把VOC的Annotations目录全部解析一遍。VOC格式里每张jpg对应一个同名的xmlxml里的object节点记录name和bndbox。这个数据集标注的是“销钉缺失”和“销钉完好”这类状态类目标类别数通常不多但每个目标框面积占整张图的比例很高属于典型大目标检测。import os import xml.etree.ElementTree as ET voc_root VOCdevkit/VOC2012 # 换成实际路径 ann_dir os.path.join(voc_root, Annotations) stats {} total_boxes 0 for xml_name in os.listdir(ann_dir): if not xml_name.endswith(.xml): continue tree ET.parse(os.path.join(ann_dir, xml_name)) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) for obj in root.iter(object): cls obj.find(name).text stats[cls] stats.get(cls, 0) 1 total_boxes 1 box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) # 统计目标面积占比判断是否真的属于大目标 area_ratio (xmax - xmin) * (ymax - ymin) / (img_w * img_h) if area_ratio 0.05: print(f小目标: {xml_name}, {cls}, ratio{area_ratio:.3f}) print(类别统计:, stats) print(总目标框数:, total_boxes)这段代码干的是摸底。跑完后你会得到两份信息类别名称集合以及面积占比分布。如果出现大量area_ratio小于0.05的框说明数据集里混入了小目标样本这对后续“按大目标设计训练策略”是一个警告信号。我一般会把面积占比低于0.03的框单列出来看看是标注噪声还是真实存在的小目标再决定要不要在训练时给这些样本加权重。2.2 把VOC转成YOLO训练格式转换脚本与四个边界坑YOLO系训练不吃VOC的xml只吃每张图一个txt、每行一个“类别 x_center y_center width height”的归一化格式。转换脚本本身不难但在这个数据集上有四个坑必须处理。import os import xml.etree.ElementTree as ET voc_root VOCdevkit/VOC2012 ann_dir os.path.join(voc_root, Annotations) label_dir labels os.makedirs(label_dir, exist_okTrue) def convert(xml_file, out_dir): tree ET.parse(xml_file) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) # 坑1有些XML的width/height是字符串int()前先去空格 img_w int(str(root.find(size/width).text).strip()) img_h int(str(root.find(size/height).text).strip()) out_name os.path.basename(xml_file).replace(.xml, .txt) with open(os.path.join(out_dir, out_name), w) as f: for obj in root.iter(object): cls obj.find(name).text # 坑2类别名如果有中文或空格这里要做映射 if cls not in class_map: print(f未知类别: {cls}, 文件: {xml_file}) continue box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) # 坑3边界框出界裁剪到图像范围内 xmin max(0, min(xmin, img_w)) xmax max(0, min(xmax, img_w)) ymin max(0, min(ymin, img_h)) ymax max(0, min(ymax, img_h)) if xmax xmin or ymax ymin: continue x_center (xmin xmax) / 2 / img_w y_center (ymin ymax) / 2 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h f.write(f{class_map[cls]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}\n) class_map {missing_screw: 0, normal_screw: 1} for xml_name in os.listdir(ann_dir): if xml_name.endswith(.xml): convert(os.path.join(ann_dir, xml_name), label_dir)四个坑分别是XML里width字段的字符串空格类别名到ID的映射必须显式定义不能直接拿文本当ID用边界框坐标偶尔出界裁剪能避免训练loss直接NaN以及目标框宽高为负时跳过。做完这步voc yolo的格式转换就干净了后面训练不会在数据加载阶段翻车。2.3 ImageSets里藏着训练验证划分的秘密VOC的Main目录下通常有train.txt、val.txt等文件列出参与训练和验证的图像名。这个数据集的发布方如果给了划分直接用没给就自己划。划分方式对最终精度影响很大尤其是电力塔材图像——同一座塔的不同角度照片之间高度相似如果随机划分验证集里会出现和训练集几乎同一视角的图片mAP虚高。import os import random random.seed(42) img_dir JPEGImages imgs [f.replace(.jpg, ) for f in os.listdir(img_dir) if f.endswith(.jpg)] random.shuffle(imgs) split_point int(len(imgs) * 0.85) train_names imgs[:split_point] val_names imgs[split_point:] with open(train.txt, w) as f: f.write(\n.join(train_names)) with open(val.txt, w) as f: f.write(\n.join(val_names)) print(f训练集: {len(train_names)} 张, 验证集: {len(val_names)} 张)如果这批图像里有拍摄杆塔的编号信息通常体现在文件名里划分前先按杆塔ID分组同一个塔的照片要么全进训练集要么全进验证集。这样验证集才有说服力。3. 为“大目标”定制检测策略从模型选型到训练参数怎么调才不浪费这批数据3.1 大目标检测为什么不需要高分辨率输入这个数据集的“大目标”属性决定了输入分辨率不用卷到1024以上。检测模型对目标的定位精度依赖特征图分辨率但大目标本身占图面积大在640x640输入下目标的长边可能占几十到上百像素小目标的“像素太稀疏”问题根本不存在。我一般直接用640x640个别框非常宽的塔材图可以试960但显存开销翻倍精度提升通常不超过1个百分点。用YOLOv5s还是YOLOv8n对这种二分类大目标任务s级或n级足够了。1209张图的规模也撑不起大模型——用YOLOv8x硬训参数量大了几十倍数据集只有一千张出头过拟合几乎是必然的。我做过的类似工业检测项目里缺失检测这类状态分类任务模型容错重点在“框得准”和“分得对”不在“认得细”。所以轻量模型加合适训练策略是性价比最高的路径。3.2 训练参数batch、epoch、学习率与锚框之间的平衡# 基于YOLOv5/YOLOv8的训练脚本精简配置实际使用按版本调整 train: model: yolov8n.pt # 轻量模型匹配1209张的规模 data: screw_dataset.yaml # 配置好train/val路径和类别数 imgsz: 640 # 大目标不需要高分辨率 batch: 16 # 显存允许的前提下尽量大 epochs: 100 # 数据量小早点启动早停 optimizer: SGD lr0: 0.01 lrf: 0.01 # 余弦退火到0.01倍初始学习率 mosaic: 0.5 # 大目标场景下mosaic概率调低 close_mosaic: 10 # 最后10个epoch关掉mosaic weight_decay: 0.0005 warmup_epochs: 3.0 box: 7.5 # box loss权重 cls: 0.5 # 分类loss权重 dfl: 1.5这里的核心不是背参数而是理解几个和大目标数据集直接相关的选择。batch取16不是因为越大越好而是1209张图、类别少太大的batch会让每个epoch的梯度更新次数太少模型还没收敛就被动进入早停。epoch给100配合早停大多数情况在60个epoch左右就能稳住。mosaic降到0.5是这个场景的关键调整。mosaic增强会把四张图拼成一张对小目标检测提升明显但对大目标反而有害——拼图后目标被“缩小”到原来的四分之一模拟了一批数据集里根本不存在的“小目标”分布训练出来的模型会在真实的小目标上过度响应比如把远处的绝缘子串误判成销钉缺失。最后10个epoch彻底关掉mosaic是为了让模型在接近真实分布的数据上做最后的精细拟合。3.3 锚框参数大目标用默认值还是重算YOLOv5系有自动锚框功能训练时会用k-means在label文件上重算锚框尺寸。对这个数据集我建议直接开autoanchor让它算。原因是大目标框的宽高比通常集中在几个固定模式——销钉缺失的框宽高比接近1:1或1:1.5而整根塔材的框可能是1:5甚至更极端。如果锚框预设不匹配可以观察到训练前期loss下降缓慢mAP在头20个epoch几乎不动。# 手动检查锚框与数据集的匹配度训练日志中会输出 # AutoAnchor: 5.83 anchors/target, 0.987 Best Possible Recall (BPR) # 如果BPR低于0.98说明需要重算锚框重算后锚框长宽比如果出现极端值比如1:20这种先别急着删——它可能对应的是塔材斜向完整框不是噪声。观察类别分布时如果框的宽高比两极分化严重考虑按目标面积分桶训练两条分支但这批1209张的规模撑不起分支结构老老实实单模型加autoanchor就够了。3.4 类别不平衡缺失样本少怎么办螺栓销钉缺失在真实巡检里是小概率事件数据集里可能只有两三成图标注了缺失类。类别不平衡会让模型偏向预测“完好”因为这样loss最小。处理方式第一选不是换loss而是先看数据分布。# 统计训练集每类的目标框数量输出到控制台 import os from collections import Counter cnt Counter() for txt in os.listdir(labels): with open(os.path.join(labels, txt)) as f: for line in f: cls line.split()[0] cnt[cls] 1 print(cnt) # 假设输出 Counter({1: 2800, 0: 900})比例约3:1如果接近3:1不用上focal loss给cls loss里的正样本权重乘以1.5~2即可。如果超过5:1就要考虑在数据层面补充缺失类样本——用已有的缺失类图像做复制粘贴增强把带缺失销钉的目标框裁剪出来随机贴到完好的塔材图上同时生成新的标注。4. 输电线路螺栓销钉缺失检测的5个踩坑记录从标注不一致到验证集虚高4.1 把“螺母缺失”和“销钉缺失”标成了同一个类现象训练后验证集mAP到0.85但实际跑巡检视频时螺母没拧紧的塔材疯狂误报。打开标注看发现有一部分xml里把“螺母缺失”也框了进来name字段标成“missing”。原因标注人员在电力术语上没对齐。“销钉”和“螺母”在图像上位置紧挨但缺失后果完全不同。数据集本身可能是多人标注的类别定义没写清楚。解决这种只能回到标注文件重新清洗。脚本把该类别的目标框裁剪出来导出jpg人工过一遍筛掉混入的螺母样本。1209张图规模不算大半天能洗完。4.2 验证集随机划分导致同塔照片泄漏mAP虚高现象训练完跑验证集mAP很高但换到另一个场景的测试集上精度掉10个点以上。原因同一条输电线路的塔材外观高度一致随机划分时同一基塔的不同照片同时进了训练集和验证集模型相当于“见过答案”。解决按文件名里的塔号前缀分组划分。文件名类似IMG_20240101_T1_001.jpg用“IMG_20240101_T1”作为分组key同一key的图像全进训练集或全进验证集杜绝泄漏。4.3 mosaic增强在大目标上的负效果现象用默认mosaic概率1.0训练loss曲线很漂亮但检测结果里出现大量小块的错误框集中在绝缘子和导线区域。原因mosaic把四张图缩小拼接大目标变成了小目标网络被迫学习了一种目标尺度分布跟真实场景不一致。另一个副作用是拼接处的目标被截断销钉缺失的框被切掉一半标注信息丢失。解决mosaic概率降到0.3~0.5最后10个epoch关闭。如果显存够直接用copy-paste增强替代mosaic对大目标更友好。4.4 白天拍摄的图训练完晚上巡检直接翻车现象白天图像训练的模型在黄昏和夜间补光拍摄的图上一片误检尤其是反光的塔材表面。原因训练集里光照分布单一。无人机巡检经常补拍夜间补光灯打在金属塔材上会产生强烈高光模型没见过这种纹理把高光区域当成了缺失区域。解决数据增强里加入亮度抖动和对比度增强HSV的H通道增强0.015S通道增强0.5V通道增强0.4同时加入随机gamma校正。如果数据确实没有夜间图增强是唯一后悔药。4.5 训练时loss正常但mAP为0现象YOLOv5训练到第10个epochbox loss正常下降但mAP一直是0。原因class_map文件里类别ID和label文本没有对应上。这个数据集如果直接拿xml里的中文类名写入txt转出来的类别ID是0或1但data yaml里的names列表顺序反了导致模型预测的是text对不上。解决训练前先跑一次验证打印class names和prediction的对应关系。最简单的方法是把names列表删掉只留nc让模型从头学类别槽位。5. 把1209张用出“万张”的效果伪标注、难例挖掘与验证闭环数据量就1209张翻不出花来但工业项目里“不够数据”是常态怎么把有限的数据榨干才是真本事。第一个技巧是伪标注。用训练好的模型对同一线路其他塔材的未标注巡检图像做推理把置信度0.95以上且框面积大于某个阈值的检测结果导成VOC格式再人工快速过一遍。这个方法在电力场景特别有效——塔材结构高度重复模型在一个塔上学到的销钉模式在另一个塔上几乎直接适用。我见过用1209张加伪标注扩到4000张的项目最终精度提升2到3个点。代价是一定要人工复核伪标注框否则会把模型的系统误差固化进训练集。第二个技巧是难例挖掘。训练完第一轮后把验证集里预测错的所有样本挑出来和训练集混合重新训。这不是常规的“加训练轮数”而是改变了数据分布让模型把注意力压到那些和正常样本非常接近的难例上。对销钉缺失检测来说难例通常是“销钉还在但被遮蔽了半边”或“背景纹理和销钉颜色一致”的图。第三个技巧是验证闭环。不要只跑官方mAP部署后记下来真实场景里的F1。这两个指标在大目标数据集上经常出现矛盾——mAP看重框的IoU但电力巡检真正关心的是“该报警的塔材有没有报”框偏一点不影响作业。我自己的习惯是部署后跑5条真实巡检航线统计误报率和漏报率用这个数据反推要不要调低置信度阈值或增加难例。最后一步做一次完整的误报图谱可视化把所有的false positive框存成缩略图拼成一张大图人眼扫一遍就能定位到是绝缘子误报、导线误报还是塔材纹理误报。这个动作不花时间但对下一轮数据补充方向的指导价值比任何抽象指标都高。回头说这个数据集1209张确实不算大但大目标属性让这个量级完全够起步。真正决定项目成败的不是数据量而是你有没有把VOC解析清楚、有没有把增强策略调对、有没有把验证集划分干净。这些都是半小时能做完的事却是精度从“能跑”到“能用”的分水岭。希望帮到你。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门