尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

万张遥感电力塔目标检测数据集:三格式标注与YOLOv8训练全攻略

发布时间:2026/9/26 6:59:44

资讯中心
01
ARTICLE

万张遥感电力塔目标检测数据集:三格式标注与YOLOv8训练全攻略

万张遥感电力塔目标检测数据集:三格式标注与YOLOv8训练全攻略
简介面向遥感目标检测与电力设施巡检场景的YOLO电力塔目标检测数据集包含10000张真实场景高清图片由LabelImg标注标注框质量较高。数据提供voc、coco、yolo三种标签格式分别存放于不同文件夹可直接用于YOLO系列模型训练适合目标检测学习者、算法工程师及电力巡检智能化项目开发人员。图像覆盖平原、山地、城市等不同地貌可有效提升模型泛化能力。压缩包共2000个文件以1985个xml标签为主另有yolo/txt标签文件、6个html训练教程和3个Python脚本整体大小约764.62MB目录清晰便于快速定位数据与脚本。目前已有655人浏览学习。通过该资源能快速拿到标准化数据并参照附赠教程完成环境配置、模型训练与自定义数据集的改造还能按需划分训练集、验证集和测试集大幅节省数据准备时间。1. 遥感电力塔目标检测数据集为什么说三格式齐全比图片数量更重要做遥感目标检测的人都有一个共识图片好找标注难凑。尤其是电力塔这种单一类别目标公开数据集里几乎找不到像样的自己标注一万张遥感图标注成本高到能劝退大部分个人开发者。这份YOLO遥感电力塔目标检测数据集包含10000张遥感影像全部标注完成并同时提供VOC、COCO、YOLO三种格式的标签文件外加划分脚本和训练教程正好补上这个缺口。我拆解这份资源时最在意的不是图片数量而是三格式齐全这一点。实际工程里你换一个框架就要换一种标签格式VOC的XML、COCO的JSON、YOLO的TXT三种格式的坐标体系完全不同手工转换极易出错。有了现成的三格式标签和划分脚本从数据集到训练只差一条命令。适合谁用正在做遥感目标检测、电力巡检相关项目的研究生和工程师以及想用现成数据快速熟悉YOLO训练流程的入门者。这篇笔记我把数据组织结构、格式坐标关系、划分脚本逻辑、训练配置和踩坑记录全部拆开讲。2. 数据形态与三种标注格式先搞懂坐标体系再动手2.1 遥感电力塔图片长什么样这份数据集的图片是遥感影像切片常见的做法是把原始大图切成512×512或1024×1024的小图方便直接送入检测网络。电力塔在遥感影像里的特征是目标小、背景杂铁塔结构呈细长线状和道路、建筑物混在一起时肉眼都容易看漏。这意味着训练时如果直接套用COCO上常用的anchor参数小目标召回率会很难看。图片格式一般是JPG文件名按编号排列。拿到底包后先不要急着训练花十分钟把图片随机抽几十张出来看一遍重点观察目标的尺度分布和背景复杂度。我的习惯是统计一下目标框的宽高比分布如果大多集中在1:1到1:3之间说明数据分布正常如果出现大量极端长宽比的目标框后面选anchor时要格外小心。2.2 VOC格式XML里存的是绝对像素坐标VOC格式的核心是每个图片对应一个同名XML文件存放在Annotations目录下。XML里最关键的是bndbox节点保存目标的左上角和右下角绝对像素坐标。annotation folderJPEGImages/folder filenameimage_00001.jpg/filename size width1024/width height1024/height depth3/depth /size object nameelectric_tower/name bndbox xmin256/xmin ymin300/ymin xmax312/xmax ymax420/ymax /bndbox /object /annotation这里有个很容易被忽略的细节VOC的坐标是绝对的像素值而且是以图片左上角为原点x轴向右y轴向下。xmin和ymin是目标框左上角xmax和ymax是右下角。如果从其他地方拿到VOC格式数据第一步要想办法确认坐标是否真的符合这个约定我遇到过有人把中心点坐标写进去的情况训练时loss直接下不来。2.3 COCO格式单个JSON文件承载全部标注COCO格式把所有图片信息和标注信息塞进一个JSON文件里一份完整的COCO标注包含images、annotations和categories三个核心字段。每张图片在images里有一条记录每个目标框在annotations里有一条记录通过image_id关联。{ images: [ { id: 1, file_name: image_00001.jpg, width: 1024, height: 1024 } ], annotations: [ { id: 1, image_id: 1, category_id: 1, bbox: [256, 300, 56, 120], area: 6720, iscrowd: 0 } ], categories: [ { id: 1, name: electric_tower } ] }COCO的bbox格式是[x, y, width, height]这是和VOC最大的区别。VOC存的是两个点COCO存的是左上角加宽高。类别ID从1开始这个细节很关键很多框架里如果背景也算作0号类别类别ID从0开始转换时错一位后面全是问题。2.4 YOLO格式归一化坐标和三者的换算关系YOLO格式每个图片对应一个TXT文本文件每行一个目标格式是类别ID 中心点x 中心点y 宽 高全部是相对于图片宽高的归一化值范围在0到1之间。0 0.27734375 0.3515625 0.0546875 0.1171875对应前面VOC例子里的坐标中心点x(256312)/2/10240.27734375宽(312-256)/10240.0546875。三种格式的换算关系用一张表格可以看得很清楚。格式坐标表示坐标原点数值范围VOCxmin, ymin, xmax, ymax左上角绝对像素COCOx, y, width, height左上角绝对像素YOLOx_center, y_center, width, height左上角归一化0~1从VOC转到COCOx取xminy取yminwidth取xmax-xminheight取ymax-ymin。从VOC转到YOLOx_center(xminxmax)/2再除以图片宽y_center同理。坐标转换的坑一般在除法和取整上YOLO格式要求浮点数保留六位小数足够不要四舍五入成整数否则小目标框会偏掉。3. 划分脚本与格式转换先防泄漏再谈训练3.1 数据集划分的三个原则拿到数据和标签之后第一步不是转格式而是划分训练集、验证集、测试集。一个科学的划分要满足三个条件比例合理、分布随机、场景隔离。比例上一般按7:2:1或者8:1:1划分。遥感数据有个特殊问题同一个区域拍出来的切片背景高度相似如果这些切片同时出现在训练集和验证集里验证分数会虚高。最靠谱的做法是按场景或者按原始大图来分——把同一张原始大图切出来的切片全部放进同一个集合而不是逐张随机分。这一点在训练教程里如果没提到自己划分时要格外留意。划分脚本做的事很直接扫描所有图片文件名按比例切分把归属信息写入TXT列表文件。VOC格式的划分文件放在ImageSets/Main/下文件名约定是train.txt、val.txt、test.txt。import os import random random.seed(42) image_dir JPEGImages all_images [f for f in os.listdir(image_dir) if f.endswith(.jpg)] all_images.sort() # 固定随机种子保证每次运行获得相同划分结果 random.shuffle(all_images) # 按7:2:1划分 train_ratio, val_ratio 0.7, 0.2 train_cnt int(len(all_images) * train_ratio) val_cnt int(len(all_images) * val_ratio) train_set all_images[:train_cnt] val_set all_images[train_cnt:train_cnt val_cnt] test_set all_images[train_cnt val_cnt:] def write_split(file_list, filename): # 只写文件名不写扩展名是VOC的约定 with open(filename, w) as f: for img in file_list: f.write(os.path.splitext(img)[0] \n) os.makedirs(ImageSets/Main, exist_okTrue) write_split(train_set, ImageSets/Main/train.txt) write_split(val_set, ImageSets/Main/val.txt) write_split(test_set, ImageSets/Main/test.txt) print(ftrain: {len(train_set)}, val: {len(val_set)}, test: {len(test_set)})这里固定random.seed(42)很关键。不固定种子的话每次跑脚本划分结果都不一样前期调参时前后两次实验的验证集不统一指标没法对比。数据量小的时候可以一次划分终身使用数据量大或者要反复做交叉验证时再把划分逻辑封装成函数。3.2 从VOC到YOLO的批量转换脚本Ultralytics YOLOv8训练时只需要YOLO格式的TXT标签所以拿到VOC格式后第一件事是批量转换。转换脚本的核心是解析XML提取坐标按图片宽高归一化然后写入TXT文件。import os import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, out_dir, class_names): tree ET.parse(xml_path) root tree.getroot() img_width int(root.find(size/width).text) img_height int(root.find(size/height).text) out_lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_names: continue class_id class_names.index(name) 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) # 防止边界值越界 xmin max(0, min(xmin, img_width)) xmax max(0, min(xmax, img_width)) x_center (xmin xmax) / 2.0 / img_width y_center (ymin ymax) / 2.0 / img_height w (xmax - xmin) / img_width h (ymax - ymin) / img_height out_lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) img_name os.path.splitext(os.path.basename(xml_path))[0] with open(os.path.join(out_dir, img_name .txt), w) as f: f.write(\n.join(out_lines)) class_names [electric_tower] xml_dir Annotations yolo_label_dir labels os.makedirs(yolo_label_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if xml_file.endswith(.xml): voc_to_yolo(os.path.join(xml_dir, xml_file), yolo_label_dir, class_names)这段代码里class_names.index(name)这个操作要确保XML里标注的类别名和列表里的完全一致大小写都不能差。我碰到过标注的人把类别写成带空格的脚本跑完labels目录里全是空文件此时很难发现因为一张两张空的还能混过去多了训练时每个batch都没有正样本。3.3 转换后的验证步骤不能省转换完成后不要急着训练先写两行代码抽查验证。随机抽三五个TXT文件看看类别ID是否在合理范围坐标值是否都在0到1之间目标框面积是否和原图对应。我之前吃过一次亏转换脚本里忘记处理坐标越界的边界值个别标注框右边界超出了图片宽度归一化后大于1训练时损失直接朝上走。可视化的验证方法是把YOLO格式的坐标换算回像素坐标用OpenCV画框叠加到原图上人眼扫一遍就能发现坐标偏移问题。这一步花不了五分钟但能省下后面几个小时的调试时间。4. 基于Ultralytics YOLOv8的训练流程环境、配置、一条命令跑通4.1 环境配置与目录结构整理Ultralytics YOLOv8是目前最主流的训练框架pip直接安装即可不过Anaconda环境里需要留意包版本的兼容性。我一般用Python 3.9配PyTorch 2.0以上版本装完ultralytics之后跑一遍自带的检测demo确认环境没问题。# 创建虚拟环境并安装必要依赖 conda create -n yolo python3.9 conda activate yolo pip install ultralytics pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118装完后把数据集整理成YOLO格式的标准目录结构。注意这里的images和labels目录需要分别存放训练和验证的图片路径要与标签路径一一对应。datasets/ electric_tower/ images/ train/ val/ test/ labels/ train/ val/ test/训练前检查的一个关键点labels/train/下每个TXT文件名要和images/train/下的JPG文件名完全匹配包括扩展名处理方式。Ultralytics框架里如果图片缺少对应标签默认当作背景图参与训练1万张图里混进几十张缺标签的损失曲线看不出大问题但精度会莫名低一截。4.2 数据集YAML配置与训练参数选择在工程目录下新建一个electric_tower.yaml文件指定数据路径和类别名称这是训练的前置条件。path: /path/to/datasets/electric_tower train: images/train val: images/val test: images/test names: 0: electric_tower类别ID必须从0开始连续排列。如果数据集的YOLO标签里类别ID是1而YAML里只有0号类别训练时会直接报错或者把标签当噪声滤掉。这个和COCO格式从1开始不同很多从COCO转过来的人会在这里翻车。训练命令本身不复杂复杂的是参数选择。yolo train dataelectric_tower.yaml modelyolov8s.pt epochs100 imgsz640 batch16从yolov8s预训练权重开始是性价比最高的选择模型尺寸适中单卡能跑精度也比nano好一截。遥感电力塔属于小目标检测imgsz设640时目标可能只有十几个像素此时可以考虑设成1024或1280来提高小目标分辨率但显存占用会同步上涨batch要相应调小。参数推荐值说明modelyolov8s.pt从预训练权重开始收敛更快imgsz640~1024目标小时用大分辨率batch16~32按显存调整OOM时减半epochs100~300遥感数据收敛慢100起步patience20验证集长期不涨就早停lr00.01数据量1万张可以稍高4.3 训练过程中的监控与常见现象训练启动后终端会实时刷新每次epoch的loss、精度和召回率。前10个epoch大概率看到loss震荡这是正常的等warmup结束后会稳定下降。遥感数据有个特点背景复杂导致收敛比常规数据集慢训练到第50个epoch左右精度可能还在缓慢爬升不要急着早停。验证集指标要看mAP50和mAP50-95两个数字。前者衡量粗略定位能力后者衡量精细定位能力。电力塔这种目标细长的检测任务mAP50能到0.9以上才算合格。如果mAP50到0.9附近卡住不动先从数据层面找问题看标注框有没有大量错位再考虑调anchor参数。我在这个数据集上训练时看到过一种现象训练loss下降很漂亮但验证mAP很低一查发现是标签里混入了大量空文件模型一直在学背景。5. 避坑记录五条从数据到训练的真实翻车经验5.1 训练时loss变成NaN前面的功夫全白费现象训练到第20个epoch左右终端输出的loss突然变成nan验证集精度直接清零。原因最常见的是学习率设置过大或者数据里出现了极端值。遥感切片如果存在全黑的图片归一化后的像素值会异常个别标注框坐标越界也会导致loss计算出现NaN。解决先把lr0从默认0.01调低到0.005重新训练。同时检查labels目录下所有TXT文件用脚本扫描坐标值是否在0到1之外。如果确认有越界坐标重新跑转换脚本并且在转换时加上边界裁剪逻辑。5.2 YOLO标签类别ID从1开始训练时所有目标被当背景现象训练能跑通loss在下降但训练集的PR曲线完全没有正样本val精度一直为0。原因VOC格式转YOLO格式时类名映射表写错了。COCO格式的类别ID从1开始直接拿COCO的JSON转YOLO没有把类别ID减1导致所有标签的类别ID变成1而数据集的类别配置只有0号类别。解决转换脚本里把class_id class_names.index(name)改成category_id - 1转完再抽查一个TXT文件确认第一列全部是0。5.3 划分脚本没有固定随机种子调参实验指标对不上现象同一个数据集同一条训练命令第一次跑mAP50是0.85第二次跑变成0.82两次验证集不一致导致无法判断改参数是否有效。原因划分脚本每次运行时重新打乱图片顺序训练集和验证集的组成每次都不同。解决在划分脚本里固定random.seed(42)划分一次后把生成的TXT文件或者目录结构打包保存后续所有实验共用同一份划分。5.4 COCO格式面积字段算错评估阶段AP异常偏低现象训练正常但跑COCO评估脚本时mAP比用YOLO格式评估低一大截。原因COCO标注里的area字段用于小目标、中目标、大目标的分类统计如果area算的是宽高之和而不是宽乘高评估结果会乱。标注转换工具一般不会主动校验这个字段。解决转换时单独计算area width * height并写入。从原始XML转COCO时这个字段必须显式计算不能默认0或者留空。5.5 验证集和训练集切片来自同一张原始大图精度虚高现象训练时验证集loss一直在降mAP50超过0.95但拿到新的遥感影像上测试效果差得离谱。原因遥感大图切片的切片之间重叠度高同一张大图切出的几十张小图被随机分到了训练集和验证集验证集实际上参与了训练。解决划分时以原始大图为单位分桶整张大图的所有切片只能进入同一个集合。如果你的划分脚本只拿到了切片后的文件名无法回溯原始大图关系那就要重新规划划分逻辑或者在训练前手动检查相邻文件名是否同时出现在train.txt和val.txt里。6. 验证与真实工程落地用三类指标确认模型真的能用模型训练完只是第一步真正要确认的是它能不能扛住实际场景。我的习惯是训练结束后马上做三件事跑验证集看指标、跑测试集对比、可视化推理结果确认目标位置准不准。先跑验证集得到最终的mAP50和mAP50-95再跑测试集。测试集在整个训练过程中没有参与过任何决策指标会有一定回落如果回落幅度超过5个百分点说明模型过拟合了此时回去加数据增强或者调大正则化系数。我见过有人把训练集指标当成模型真实水平汇报到项目周报里然后被测试集打脸这个教训在工程上不能犯。可视化这步最容易被跳掉但最有价值。随机抽几十张测试集图片把推理结果画框保存出来对着看电力塔的检测框有没有偏移。遥感影像上电力塔经常在复杂背景里比如田地、山体、房屋密集区人眼能看出模型在哪些场景下漏检在哪些场景下误检。这一步能帮你判断模型部署后的适用边界。写一段简单的推理脚本检查检测框位置from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) results model.predict(sourcetest_images/image_00042.jpg, conf0.25, saveTrue) for r in results: boxes r.boxes.xyxy.cpu().numpy() # xyxy像素坐标 scores r.boxes.conf.cpu().numpy() for box, score in zip(boxes, scores): x1, y1, x2, y2 [int(v) for v in box] print(fbox: ({x1}, {y1}) - ({x2}, {y2}), conf: {score:.3f})置信度阈值设置有个经验值遥感小目标场景下默认的conf0.25会漏掉很多低置信度但真实存在的目标我的习惯是先调到0.1跑一遍把输出框全看一遍再决定最终阈值。电力塔的纹理特征在遥感影像上不算特别显著有些塔在阴影里置信度只有0.2左右但从工程角度依然值得检测出来。从那以后我每次拿到遥感检测数据集都会在训练前先跑一遍数据完整性检查脚本核对每个集合的图片和标签数量、扫描越界坐标、抽查五个TXT可视化确认坐标没有偏移把这套流程强制走一遍再开始训练。坏数据带偏模型这种事防比修便宜得多。这套检查步骤配合这份数据集的划分脚本做下来第一轮训练基本不会翻车希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。