ARTICLE DETAIL

资讯详情

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

YOLO无人机航拍绝缘瓷瓶数据集:训练、格式转换与避坑指南

YOLO无人机航拍绝缘瓷瓶数据集:训练、格式转换与避坑指南 简介面向无人机电力巡检与目标检测的研究者提供真实航拍场景下的输电线路绝缘瓷瓶高质量图片场景覆盖丰富经LabelImg逐张标注框体质量可靠可用于YOLO系列模型训练与算法验证。压缩包内同步整理VOCxml、COCOjson与YOLOtxt三种标签格式分文件夹存放标签与图像一一对应导入主流检测框架即可使用。全部文件合计1281个除421张jpg图像及对应标签外还包含3个Python数据集划分脚本、1个yaml模型配置和6个HTML版环境搭建与训练教程整体约941.93MB脚本可自定义划分训练集、验证集与测试集教程分Linux和Windows系统覆盖环境配置、案例修改到训练启动的完整流程降低实操门槛。已有334人学习下载适合需要真实电力场景数据支撑、希望获得标准化标注与完整训练流程指导的算法初学者或项目开发者。1. YOLO无人机航拍绝缘瓷瓶数据集巡检检测模型的第一份训练资产做输电线路巡检的人应该都有同感无人机飞一圈能拍上千张塔架照片但真正要找出绝缘子自爆、破损、闪络痕迹靠人眼在电脑前逐张盯一天下来眼睛发花效率极低。用YOLO这类目标检测模型做自动识别瓶颈从来不是模型结构而是标注数据——公开数据集里几乎没有针对输电线路绝缘瓷瓶的航拍样本。这份YOLO无人机航拍输电线路绝缘瓷瓶数据集解决的正是这个痛点真实无人机航拍场景、使用labelimg人工标注、标注框质量高并且同时提供VOC(xml)、COCO(json)、YOLO(txt)三种格式标签拿到手不用再折腾格式转换直接能喂给YOLO系列训练。附带的划分脚本和Linux/Windows双环境训练教程让刚入门目标检测的新手也能走通全流程也适合电力巡检方向的毕设课题和工程预研。2. 三类标签格式的内部结构VOC、COCO与YOLO标签怎么读、怎么换2.1 同一份标注为什么要导出三种格式很多人在接触目标检测时会疑惑明明是同一批图片、同样的框为什么标注文件要搞出XML、JSON、TXT三种花样因为不同训练框架和工具链对输入格式的要求完全不一样。Ultralytics YOLO系列v5/v8/v11默认读取TXT格式的标签文件每个txt对应一张图片文件名与图片同名MMDetection、Detectron2这类框架常用COCO格式的单个JSON文件所有图片的标注信息汇总在一起而VOC的XML格式则是早期目标检测最通用的标准很多自研工具和数据处理脚本都在用它。如果拿到手的只有一种格式碰到换框架的场景就得重新转格式中间还要担心坐标换算出错。这份数据集把三种格式全部切好分开存放等于把数据预处理中最容易出错的一步省掉了。用的时候只要按你选定的框架找到对应文件夹下的标签文件即可。2.2 用Python批量核对标签坐标是否正常无论是自己标注还是拿到别人的数据集第一步别急着训练先把标签文件读出来核验一遍。标注格式错了后面的训练全是白费功夫。下面这段脚本可以同时读取三种格式的标签信息把关键坐标打印出来做抽查。import xml.etree.ElementTree as ET import json import os # 以图片 94.jpg 为例 img_name 94 # 1. 检查 VOC xml 格式 xml_path flabels/voc/{img_name}.xml if os.path.exists(xml_path): tree ET.parse(xml_path) root tree.getroot() for obj in root.findall(object): name obj.find(name).text bndbox obj.find(bndbox) xmin int(bndbox.find(xmin).text) ymin int(bndbox.find(ymin).text) xmax int(bndbox.find(xmax).text) ymax int(bndbox.find(ymax).text) print(f[VOC] class{name}, bbox({xmin}, {ymin}, {xmax}, {ymax})) # 2. 检查 COCO json 格式 coco_path labels/coco/annotations.json if os.path.exists(coco_path): with open(coco_path, r, encodingutf-8) as f: coco_data json.load(f) for ann in coco_data[annotations]: # coco 的 bbox 是 [x, y, width, height] x, y, w, h ann[bbox] print(f[COCO] category_id{ann[category_id]}, fbbox({x:.1f}, {y:.1f}, {w:.1f}, {h:.1f})) # 3. 检查 YOLO txt 格式 txt_path flabels/yolo/{img_name}.txt if os.path.exists(txt_path): with open(txt_path, r, encodingutf-8) as f: for line in f.readlines(): parts line.strip().split() # yolo 格式是 class_id, x_center, y_center, width, height全部归一化 cls_id, x_c, y_c, w, h parts print(f[YOLO] class_id{cls_id}, center({x_c}, {y_c}), fsize({w}, {h}))这里有几个关键点要说明VOC格式里的bndbox是像素坐标系下的绝对坐标单位是像素值左上角xmin/ymin到右下角xmax/ymaxCOCO格式虽然也是像素值但存的是[x, y, width, height]是左上角坐标加宽高YOLO的TXT格式则是归一化坐标所有值除以图片宽高后落在0到1之间。三种格式的坐标表示差异很大转换时最容易出错的就是把YOLO的归一化坐标当成像素坐标直接用或者反过来。2.3 标注格式转换的常见误用边界拿到这份数据集后多数人直接用YOLO格式训练这没问题。但如果你想换成COCO格式跑MMDetection或者拿VOC格式做数据增强实验最好先搞清楚两件事第一三种格式的类别ID顺序是否一致。这份数据集的voc和yolo文件夹里类别ID是保持一致的但COCO的categories字段里ID从多少开始、是否包含背景类0表示背景需要打开JSON的categories字段确认。第二同一个目标的框在三种格式里的数值精度不同YOLO的txt一般保留6位小数XML里是整数JSON里可能是浮点数。做数据划分时一定要保证三种格式的标签同步划分否则会出现图片在训练集、标注还在验证集的错位问题。3. 环境搭建与数据集划分从Anaconda到划分脚本3.1 Linux/Windows环境搭建的要点数据集附带了两套HTML教程分别覆盖Linux和Windows的YOLO环境搭建。实际项目里我的习惯是Windows机器用来做数据标注和快速验证Linux服务器用来跑正式训练。无论哪个平台核心步骤都是先把Anaconda装好然后用conda创建独立的Python环境再安装对应版本的PyTorch和Ultralytics YOLO。# 创建独立环境避免污染系统Python conda create -n yolo python3.9 -y conda activate yolo # 安装PyTorch注意CUDA版本要和显卡驱动匹配 # 以CUDA 11.8为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 安装YOLO训练框架 pip install ultralytics这里有一个经验之谈PyTorch和CUDA的版本匹配是最容易翻车的环节。装完之后务必跑一段验证代码确认GPU真的能被调用不要等到训练跑起来才发现用的是CPU那速度会让人怀疑人生。验证方法是python -c import torch; print(torch.cuda.is_available())输出True才说明CUDA可用。3.2 数据划分脚本怎么用比例、随机种子与同步数据集里的划分脚本HTML文档已经写好了完整实现核心逻辑是设定train/val/test比例将图片和对应的标签文件按同一随机种子切分。我一般建议按8:1:1划分训练集、验证集、测试集样本量少时可以放宽到7:2:1。关键是脚本里的随机种子random seed必须固定否则每次运行划分结果都不一样会跟后续实验记录对不上。另外划分必须同步操作图片和标签——先打乱图片列表再按索引同时把图片、XML、JSON中的对应项分到同一集合。import os import random import shutil # 固定随机种子保证每次划分结果一致 random.seed(42) # 假设图片都在 images/ 文件夹下 all_images [f for f in os.listdir(images) if f.endswith(.jpg)] random.shuffle(all_images) train_ratio, val_ratio 0.8, 0.1 train_n int(len(all_images) * train_ratio) val_n int(len(all_images) * val_ratio) # 注意test 集合不单独给比例剩余部分自动归为测试集 sets { train: all_images[:train_n], val: all_images[train_n:train_n val_n], test: all_images[train_n val_n:] } # 建立图片和标签文件的映射关系 for split_name, img_list in sets.items(): os.makedirs(fdataset/{split_name}/images, exist_okTrue) os.makedirs(fdataset/{split_name}/labels, exist_okTrue) for img in img_list: base os.path.splitext(img)[0] # 图片复制到对应集合 shutil.copy(fimages/{img}, fdataset/{split_name}/images/) # YOLO 标签同步复制 if os.path.exists(flabels/yolo/{base}.txt): shutil.copy(flabels/yolo/{base}.txt, fdataset/{split_name}/labels/) # VOC 和 COCO 同理这里按需复制即可这段脚本的重点有两个random.seed(42)固定随机种子保证可复现先打乱图片列表再按索引切片保证图片和标签的分组完全一致。实际使用中如果你的数据有类别不均衡问题单纯随机划分可能让某一类样本全部集中在训练集而验证集里没有这时候建议改成按类别分层的划分方式——先按类别分组再在每个组内按比例划分最后合并。但这份绝缘瓷瓶数据集的类别分布相对均匀简单随机划分就够用。3.3 划分后先做一致性核验划分完成别急着训练。我见过太多人栽在这里图片和标签都分完了结果训练时发现验证集里某张图的标签文件不存在或者txt里写的是空文件。所以每次划分完我都会跑一遍一致性检查脚本。# 统计每个集合的文件数量确保图片和标签一一对应 for split in train val test; do echo $split echo 图片数: $(ls dataset/$split/images/*.jpg 2/dev/null | wc -l) echo 标签数: $(ls dataset/$split/labels/*.txt 2/dev/null | wc -l) done如果图片数和标签数对不上优先检查是不是有图片本来就没标注这类图片在标注阶段会被过滤掉或者标签文件命名和图片不一致。还有一种情况是txt文件存在但内容是空的宽高为0的目标训练时会被框架自动忽略但最好提前清理干净。4. 训练自己的检测模型配置yaml、调参、看训练日志4.1 数据配置YAML与类别文件怎么写YOLO训练前需要准备一个数据描述文件告诉框架图片路径、标签路径、类别数量、类别名称。这里写一个标准的数据配置。# dataset.yaml # 注意这里的路径是相对于训练脚本执行位置的相对路径 # 也可以写绝对路径但不推荐换机器会失效 path: ./dataset # 数据集根目录 train: train/images # 训练集图片目录 val: val/images # 验证集图片目录 test: test/images # 测试集图片目录可省略 # 类别定义数量和名称必须与标签txt里的class_id严格对应 nc: 1 names: 0: insulator配置yaml文件有几个细节容易出错path字段写相对路径时训练命令执行的工作目录必须正确否则框架找不到图片nc的数量必须和names列表长度一致最关键的是names里的顺序必须和标注时labelimg里设定的类别顺序完全一致——labelimg里第一个类别对应class_id 0不是1。这份数据集的标注类别是绝缘瓷瓶单类检测nc: 1类别名insulator。4.2 训练启动参数与超参选择配置写好后就可以启动训练了。假设你用的YOLOv8或者v11训练命令大同小异。以一个实际的训练任务为例说明参数怎么设。python train.py \ --data dataset.yaml \ --weights yolov8s.pt \ --epochs 200 \ --batch 16 \ --imgsz 640 \ --device 0 \ --patience 30参数说明--weights指定预训练权重建议用COCO预训练模型作为起点迁移学习能明显加速收敛--epochs设为200配合--patience 30做早停如果连续30个epoch验证集指标没有提升就自动停止能省不少时间--batch的大小受显存限制显存不够时优先把batch调小而不是降低图片尺寸--imgsz 640是训练图片分辨率航拍图片里绝缘子目标较小可以考虑用768或1024但显存消耗会翻倍。刚开始跑实验我一般先用640快速验证流程通不通再提分辨率。4.3 训练日志里看什么loss曲线和mAP指标训练启动后不要只盯着终端输出发呆。YOLO的训练进程会实时打印box_loss、cls_loss、dfl_loss、mAP50、mAP50-95这些指标。重点看两个东西一是box_loss是否在稳步下降二是mAP50是否在持续上升。如果loss前几十个epoch就降到很低但mAP一直上不去大概率是标注里有问题比如框偏了、类别标错了如果loss出现剧烈抖动先检查batch size是否太小、学习率是否过高。训练结束后框架会在runs/detect/train/目录下生成weights/best.pt和weights/last.pt。注意用best.pt而不是last.pt做推理——last.pt是最后一个epoch的权重可能已经过拟合。验证模型效果的命令也很简单python val.py \ --data dataset.yaml \ --weights runs/detect/train/weights/best.pt \ --batch 16验证输出会给出精确率Precision、召回率Recall、mAP50和mAP50-95四个核心指标。绝缘子检测这类目标尺度小mAP50的参考价值比mAP50-95更直观mAP50能到0.85以上基本具备实用价值。5. 避坑与排查五个翻车现场与解决记录5.1 现象换了一台机器训练报错提示找不到图片文件训练在自己机器上好好的把数据集和代码拷到服务器上就报了一个找不到图片的路径错误。原因yaml配置文件的path字段写的是本机绝对路径比如C:/Users/xxx/dataset换机器后路径不存在了。解决统一改成相对路径所有训练命令在数据集根目录的上级目录执行。或者写一个环境变量动态拼接路径但项目里最简单的做法是从一开始就严格使用./dataset这类相对路径让文件夹结构固定下来。5.2 现象训练正常跑完但验证阶段模型几乎检不出任何目标训练loss正常下降mAP却接近0拿训练集图片测试也检不出目标。原因检查了标签文件和图片发现YOLO的txt文件内容全部是归一化坐标但训练时dataset.yaml里指定的图片目录是原始图片而标注其实是基于尺寸不同的原图做的——一旦图片做过resize旧坐标就不匹配了。另一类常见原因是标签txt里的class_id超过了nc值比如nc: 1但txt里写了1实际上是第二类框架不会报错但模型学不到有效特征。解决跑一遍本文第2.2节的核验脚本逐张检查标签坐标是否在[0,1]区间class_id是否小于nc。这类问题用脚本扫一遍五分钟就能发现靠肉眼翻标签文件能看到怀疑人生。5.3 现象训练时loss出现NaN训练到一半box_loss突然变成nanloss曲线断崖式消失。原因大概率是学习率过大导致梯度爆炸或者batch size太小加上数据集里出现了极端样本比如标注框宽高为0的异常数据。解决先检查数据集里有没有空标签和宽高为0的框清理后再训练。如果问题还在把初始学习率从默认的0.01调低到0.001或者开启warmup让学习率前几个epoch缓慢爬升。遇到NaN不是玄学按这个顺序排查解决率很高。5.4 现象训练时显存溢出OOM程序直接中断--batch 16启动后没跑几步就报CUDA out of memory。原因模型输入分辨率太高或batch太大加上背景的航拍图片内容复杂中间特征图占显存远超预期。解决优先把batch调低到8或4同时把--workers降低避免数据加载线程抢占显存。如果1024分辨率下batch只能设到2果断放弃高分辨率方案用640训练后推理时再放大输入尺寸效果差距没那么大。5.5 现象推理时误检严重把非绝缘子的物体也框出来训练完拿一张巡检照片测试模型框出了好几个本不该框的目标。原因后处理时的置信度阈值设得太低默认的--conf 0.25对航拍小目标来说不够用。小目标本身的置信度普遍偏低很多误检框的置信度在0.2到0.3之间。解决推理时把--conf提高到0.4到0.5同时配合--iou 0.45做NMS过滤。这个调节过程性价比极高——不需要重新训练只改两个参数就能明显减少误检。如果提阈值后漏检变多再考虑用高分辨率推理或增加训练样本。6. 迁移学习与验证手段让模型在真实巡检场景里可用6.1 用预训练权重做微调的正确姿势很多第一次训练的人会直接不指定--weights从头训练这是对航拍小目标数据集最不友好的做法。绝缘子检测本质上是在COCO预训练模型的基础上做领域迁移预训练权重已经学会了通用的边缘、纹理、形状特征你要做的只是让它适应航拍视角下的绝缘子外形。具体操作上用yolov8s.pt起步比自己从零训练至少节省一半时间最终精度也会更高。如果你的目标是追求极致精度可以尝试yolov8m.pt或yolov8l.pt代价是显存占用和训练时间成倍增长。工程项目的经验是先用s模型跑通全流程确认数据和配置没问题后再换大模型刷精度。6.2 验证集、测试集与置信度门限的调优闭环模型训练完我习惯做三件事第一看验证集的PR曲线确定精确率和召回率的平衡点第二直接在测试集上跑推理保存可视化结果图肉眼检查每张图的检测框和置信度第三根据可视化结果微调置信度门限。# 推理并保存可视化结果 python detect.py \ --weights runs/detect/train/weights/best.pt \ --source test/images \ --conf 0.4 \ --iou 0.45 \ --save-txt \ --save-conf \ --project runs/detect/test_inference--save-txt会把检测结果保存成txt--save-conf同时保存每个框的置信度分数。这两样东西配合起来就能快速统计测试集上哪些图片漏检最严重、哪些误检分数最高反过来决定要不要补充标注数据。我一般会在第一次推理时把--conf设成0.3看全量检测结果然后再逐步提阈值对比不同阈值下的误检数和漏检数找到最适合当前场景的平衡点。6.3 导出与部署前的检查清单模型性能达标后要部署到实际巡检流程里最后一步是导出成ONNX或TensorRT格式这一步很多人会忽略。ONNX格式的好处是跨平台部署灵活TensorRT则是NVIDIA显卡上推理速度的极限优化。导出之前记得再检查一遍输入尺寸和batch size部署端的图片输入分辨率需要跟训练时保持一致否则检测精度会下降。# 导出ONNX格式固定batch为1 yolo export modelruns/detect/train/weights/best.pt formatonnx imgsz640 batch1导出后用ONNX Runtime跑一遍同样的测试图和PyTorch推理结果对比mAP应该基本一致如果偏差过大说明导出流程有问题。从那以后我每次拿到新的数据集都会强制走一遍这套流程核验标签格式、固定种子划分数据、小模型快速跑通、调置信度门限、导出部署格式。整套流程走下来绝缘子检测模型的落地周期基本能控制在一周之内。希望帮到你。本文还有配套的精品资源点击获取
返回列表