ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

YOLO卫星遥感数据集:三种标签格式与训练全流程实践

YOLO卫星遥感数据集:三种标签格式与训练全流程实践 简介YOLO卫星遥感多类别检测数据集提供1000张真实场景高清遥感图片覆盖多样地物目标使用LabelImg逐框标注质量较高适合作为目标检测入门与算法验证的数据基础。资源内已转换出VOC(xml)、COCO(json)、YOLO(txt)三种格式标签分目录存放可直接接入YOLOv5/YOLOv8等主流训练流程省去自行格式转换的麻烦。压缩包共包含2000个文件除标注数据外还有Python划分脚本、YAML配置以及环境搭建与训练教程HTML文档帮助使用者一键生成训练集、验证集和测试集并快速完成Linux/Windows下的环境配置与自定义数据训练。整体包体约114.64MB文件结构清晰便于按需取用。目前已有635人学习下载适合遥感图像处理学习者、算法开发人员以及需要高质量标注数据完成课程设计或项目实践的读者。配套教程与脚本能够有效降低YOLO系列模型的入门门槛使数据准备、环境搭建、模型训练形成完整闭环。1. 一套卫星遥感数据把“能直接训练”这件事说透搞目标检测的人多少都经历过这种痛苦模型选好了环境搭好了结果卡在数据上。要么标注格式跟框架对不上要么图片和标签对不齐要么划分脚本写得像黑匣子。这份YOLO卫星遥感多类别检测数据集罕见地在一份压缩包里把训练所需的几块拼图一次给齐了1000张高质量遥感图片同时带VOC、COCO、YOLO三种格式标签各自独立成文件夹外加三种划分脚本和配套训练教程。它不是让你自己去做标注、磨格式而是把“标注好、分好类、能开训”这件事直接端到面前。适合做目标检测课程设计、毕设或遥感方向算法验证的从业者也适合刚接触YOLO、想找一份靠谱数据跑通全流程的新手。2. 三种标签格式的对应关系从 XML 到 JSON 再到 TXT2.1 一套标注三种格式为什么数据集要做到“开箱即用”遥感检测区别于普通街景目标检测的难点在于目标尺度小、方向任意、背景复杂单类别能跑通不代表多类别能稳定。这套数据集在标注阶段就做了三份标签省去的是每个使用者都要重复做的格式转换。VOC 格式以 XML 文件存放目标框核心是bndbox下的四个绝对像素坐标COCO 格式以 JSON 组织数据核心是images、annotations、categories三张表YOLO 格式则是每个图片配一个同名 TXT每行记录class_id x_center y_center width height且四个数值都归一化到 0~1 区间。三种格式要表达的是同一批框只是组织方式不同。VOC 和 COCO 的坐标是绝对值YOLO 是相对值VOC 和 YOLO 的类别是数字编号COCO 的类别有id和name双向映射。理解这个对应关系是后面所有操作的地基。2.2 格式对齐校验用脚本确认三份标签的一致性拿到数据集后第一件事不是急着开训而是先验证三份标签是否严格对齐。我一般会写一个快速校验脚本随机抽几十张图把 YOLO 的 TXT 转成 VOC 的 XML 格式再跟原 XML 做坐标误差对比。import os import numpy as np import xml.etree.ElementTree as ET def yolo_txt_to_boxes(txt_path, img_w, img_h): boxes [] with open(txt_path, r) as f: for line in f.readlines(): cls_id, cx, cy, w, h map(float, line.strip().split()) # 反归一化把相对坐标还原成绝对像素坐标 x1 (cx - w / 2) * img_w y1 (cy - h / 2) * img_h x2 (cx w / 2) * img_w y2 (cy h / 2) * img_h boxes.append((int(cls_id), x1, y1, x2, y2)) return boxes def voc_xml_to_boxes(xml_path): boxes [] tree ET.parse(xml_path) root tree.getroot() for obj in root.iter(object): cls_name obj.find(name).text bnd obj.find(bndbox) # VOC 的 bndbox 是整数像素坐标YOLO 转出来是浮点要做容差对比 x1 float(bnd.find(xmin).text) y1 float(bnd.find(ymin).text) x2 float(bnd.find(xmax).text) y2 float(bnd.find(ymax).text) boxes.append((cls_name, x1, y1, x2, y2)) return boxes # 示例读一张 512x512 的遥感图对应的两份标签 img_w, img_h 512, 512 yolo_file labels/001.txt voc_file Annotations/001.xml yolo_boxes yolo_txt_to_boxes(yolo_file, img_w, img_h) voc_boxes voc_xml_to_boxes(voc_file) print(fYOLO 框数: {len(yolo_boxes)}, VOC 框数: {len(voc_boxes)})这段脚本的逻辑很直接YOLO 归一化坐标乘以图片宽高还原成像素坐标VOC 从 XML 里直接读绝对坐标然后逐框比对。参数上要注意两点一是img_w、img_h必须和实际图片分辨率一致遥感图经常出现 1024x1024 或 640x640 的输入如果图片有 EXIF 旋转信息读出来尺寸可能和实际不符二是对比时建议留 2~3 像素误差容限因为 YOLO 归一化再反算会引入浮点精度损失lableimg 标注的整数框和换算结果天然有细微差别。跑完这个校验三份标签的一致性心里就有底了。2.3 COCO JSON 的依赖关系先建categories再建annotationsCOCO 格式看似复杂但拆开就三条线images表记录每张图的id、file_name、width、heightcategories表定义每个类别的id和nameannotations表则是每条框记录通过image_id关联到具体图片。训练时框架会先读categories建立类别索引再遍历annotations取框的bbox字段这个字段是[x, y, width, height]的绝对坐标数组顺序和 VOC 的xmin ymin xmax ymax不一样是xmin ymin w h。校验这个文件最容易踩的坑是category_id从 1 开始还是从 0 开始以及annotations里是否出现image_id在images表中找不到的情况。我借这个数据集做老师分配的任务时都是先用 json 库把categories打印出来确认类别顺序再统计annotations数量跟 VOC 标签里的object总数是否相等。三份标签数量完全一致才有资格说“可以直接用于训练”。3. 划分脚本与 train_list.txt从原始数据到可训练目录3.1 三个划分脚本到底有什么区别压缩包里附带三个划分脚本一个做“训练集 验证集 测试集”三划分一个做“训练集 验证集”两划分还有一个是split_train_val生成ImageSets下 TXT 文件的脚本。初学者很容易把这三个当成同一种东西实际上分工完全不同。两划分脚本服务于“只要训练完看个效果”的快速验证场景三划分脚本服务于“训完要交测试报告”的课程设计或项目交付场景因为最终测试分数必须来自模型没见过的图片ImageSets脚本是为老版本 YOLOv3/YOLOv4 服务的那代框架要求先把图片名写进train.txt、val.txt再由训练代码按 TXT 列表去读图。现在的 YOLOv5/v8 系列只需要data.yaml里指向train和val两个文件夹所以三划分脚本反而更常用。3.2 用脚本做划分核心是“移动还是复制”和“随机种子”import os import random import shutil def split_dataset(image_dir, label_dir, output_dir, train_ratio0.7, val_ratio0.2, seed42): 按比例划分图片和对应标签到新目录 - train_ratio: 训练集比例 - val_ratio: 验证集比例测试集 1 - train_ratio - val_ratio - seed: 随机种子固定保证每次划分结果一致 random.seed(seed) all_images [f for f in os.listdir(image_dir) if f.lower().endswith((.jpg, .jpeg, .png))] random.shuffle(all_images) train_cnt int(len(all_images) * train_ratio) val_cnt int(len(all_images) * val_ratio) train_files all_images[:train_cnt] val_files all_images[train_cnt:train_cnt val_cnt] test_files all_images[train_cnt val_cnt:] for split_name, file_list in zip([train, val, test], [train_files, val_files, test_files]): split_img_dir os.path.join(output_dir, split_name, images) split_label_dir os.path.join(output_dir, split_name, labels) os.makedirs(split_img_dir, exist_okTrue) os.makedirs(split_label_dir, exist_okTrue) for img_name in file_list: # 图片和标签只共文件名不同扩展名复制而非移动避免误操作毁掉原目录 shutil.copy(os.path.join(image_dir, img_name), split_img_dir) label_name os.path.splitext(img_name)[0] .txt if os.path.exists(os.path.join(label_dir, label_name)): shutil.copy(os.path.join(label_dir, label_name), split_label_dir) print(f划分完成: train{len(train_files)}, val{len(val_files)}, test{len(test_files)}) split_dataset(images, labels, dataset_split, train_ratio0.7, val_ratio0.2)这段脚本用random.shuffle打乱图片列表再按比例切三段。注意几个细节第一固定seed否则每次运行划分结果都不同训练日志就对不上了第二用shutil.copy不用shutil.move保留原始数据等于留了后悔药划分错了随时可以重跑第三os.path.splitext(img_name)[0] .txt是标准的同名标签匹配方式遥感数据集偶尔会把标签放在labels目录后如果图片名带特殊字符这个匹配逻辑也要跟着调。3.3 train_list.txt 在训练里的角色train_list.txt是这套资源里的附加文件通常逐行列出训练用的图片相对路径。YOLOv5/v8 默认不读这个文件它更多是给早期 YOLO 版本或自己写的训练脚本用的。如果教程文档里明确要求使用它常见做法是手动改成一个data.yaml# dataset.yaml 示例在根目录新建这个文件 train: dataset_split/train/images val: dataset_split/val/images nc: 6 names: [aircraft, ship, storage_tank, vehicle, harbor, bridge]需要注意nc必须跟标签里最大的class_id 1一致names的顺序也必须跟 lableimg 标注时定义的类别顺序一致。否则训练能跑但 mAP 计算结果会把类别错位——其实训练时损失函数不报错真正翻车的是最后画混淆矩阵的时候。这个顺序问题在第 5 章单独讲这里先记住一点YOLO 不校验类别名只认编号。4. 环境搭好、数据路径配对把训练教程吃到嘴里4.1 Linux 路线Ubuntu 环境安装与 CUDA 驱动版本匹配这套资源付了两个 HTML 教程一个 Linux 一个 WindowsWindows 里还专门拆了一篇 Ubuntu 环境安装教程。搭 YOLO 环境最容易翻车的就是 Ubuntu 显卡驱动和 CUDA 版本对不上。先跑一遍nvidia-smi看驱动支持的最高 CUDA 版本再决定装 PyTorch 的 CUDA 版本。# 1. 查看 GPU 驱动和系统显存 nvidia-smi # 2. 用 conda 建一个干净环境Python 3.10 兼容性最好 conda create -n yolo python3.10 -y conda activate yolo # 3. 安装对应 CUDA 版本的 PyTorch这里以 cu121 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 # 4. 克隆 YOLOv5 仓库并安装依赖 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt参数说明cu121指 CUDA 12.1需要驱动版本在 525 以上如果nvidia-smi显示驱动支持最高 12.0就得换cu118版本。装完跑python -c import torch; print(torch.cuda.is_available())输出True才算环境通。Linux 版本教程里多半是这套流程核心就是先驱动后 CUDA 再 PyTorch顺序反了会浪费大量时间排查 import 报错。4.2 Windows 路线conda 是最省事的依赖隔离方式Windows 上最麻烦的是路径分隔符和 OpenCV 的 DLL 冲突。不要直接在全局 Python 里装强制建 conda env否则某天装了个新包把 OpenCV 版本顶掉训练时读图就静默失败。Windows 版教程里给出的流程通常是# PowerShell 或 Anaconda Prompt 里执行 conda create -n yolo python3.9 -y conda activate yolo pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt这里把 Python 版本换成 3.9 的原因是 Windows 上部分依赖对 3.10 的支持不够稳。注意git clone时不要选带中文或空格的路径YOLO 的Path模块在 Windows 上遇到中文路径会出诡异问题表现是图片找得到但权重保存失败。4.3 数据集 YAML 修改路径、类别数、类别名逐项核对假设已经按第 3 章脚本划分出dataset_split/train和dataset_split/val接下来把数据集的 YAML 文件指到这两个目录。VOC 和 COCO 标签在这个环节用不上YOLO 训练直接读 TXT。常见做法是新建remote_sensing.yaml# 路径以项目根目录为基准用相对路径避免迁移后失效 train: dataset_split/train/images val: dataset_split/val/images nc: 6 names: [aircraft, ship, storage_tank, vehicle, harbor, bridge]修改后启动训练python train.py --data remote_sensing.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100 --name remote_v1--img 640是训练分辨率遥感小目标建议直接上 1024 或 1280代价是显存占用增大--weights yolov5s.pt用预训练模型做迁移学习比从零训收敛快得多代价是如果新数据集类别和 COCO 差异大前几轮损失会震荡。4.4 训练日志里怎么看“真收敛了”训练不是跑完就算完。重点盯三个指标box_loss应该持续下降obj_loss是目标置信度损失如果降不下去说明有小目标漏检mAP0.5在第一个 epoch 之后从 0 开始爬升是正常的如果 20 个 epoch 后还在 0 附近基本可以断定标签有误或类别配置错误。Windows 和 Linux 的教程 HTML 里一般都有对应的日志解读段落配合这份数据的预期类别来看前几个 epoch 的 mAP 冲到 0.3 以上说明数据质量没问题。5. 避坑排查标注、划分与训练阶段的五个翻车现场5.1 训练时提示 “No labels found in ...”现象启动训练后几乎立即警告找不到标签文件的路径。原因YOLO 期望图片和标签分别在images和labels目录下且两者目录结构保持对应。划分脚本如果只把图片复制了标签文件夹没建全就会触发这个警告。解决回到split_dataset脚本确认split_label_dir确实创建了并写入了文件。常见做法是打印每个划分目录下的文件计数确认图片数和标签数相等后再开训。5.2 某些图片训练时显示 “corrupt JPEG”现象训练中断提示 OpenCV 无法解码某张 JPEG。原因遥感图片可能有特殊色彩空间或压缩参数lableimg 能打开不代表 OpenCV 能解码偶发性的截断文件也会这样。解决不要只删掉这张图会连带标签一起失配。常见做法是把整批图用cv2.imdecode重编码一遍统一转成标准 JPEG 或 PNG 再训练。5.3 mAP 异常低但损失是正常下降的现象损失在降验证集的 mAP 却一直贴着 0。原因典型的数据集划分翻车——验证集和训练集来自同一场景的不同截图模型学到的几乎是无意义的场景记忆而非类别特征另一种情况是标签类别编号和data.yaml里names顺序不一致VOC 格式第 0 号类对应vehicleYOLO 的 TXT 里第 0 号对应ship模型从第一轮就学错了语义。解决固定随机种子重新划分确保验证集和训练集在空间上分离写一个脚本读取 TXT 标签和names列表逐类别统计框数量人工核对语义。5.4 显存不足batch size 调小后精度暴跌现象CUDA out of memory强行把--batch从 16 降到 4 后损失曲线剧烈震荡。原因batch 太小导致 BN 层统计量不稳定。遥感大图用 640 分辨率输入时batch 4 确实容易崩。解决不要直接降 batch优先降--img到 512如果坚持大图训练尝试开启梯度累积。常见做法是把 batch 保持 16、img512训练 100 个 epoch再用--img 1024微调 20 个 epoch效果往往比一口吃成大图更好。5.5 标签框越界归一化坐标出现大于 1 或小于 0现象训练时assert报错提示cx或w超出 [0,1] 区间。原因使用 lableimg 标注时物体边缘贴图边界很容易把框画到图片外导出的 XML 是绝对坐标没问题的但转成 YOLO 归一化坐标后会出现负值或超 1 的值。解决在预处理阶段加一个裁剪脚本把所有归一化坐标强制裁剪到 [0,1] 内同时剔除面积小于一定阈值的框。这类清洗是一次性的做一次后面所有训练都受益。6. 进阶技巧把 1000 张图的价值用到极限6.1 用小模型先跑 baseline再决定要不要上高分模型第一次训练建议直接用 YOLOv5s而不是一上来就调大模型。s 模型训练一轮的时间大概是 l 模型的三分之一足够把数据问题、标签问题全部暴露出来。等 s 模型在mAP0.5上到一个稳定值后再用这个结果做确认如果 mAP 在 0.5 以下先怀疑数据问题而不是模型容量不够。6.2 难例挖掘用训练好的模型给未标注图片打粗标签1000 张图训出的模型大概率在航拍密集场景下会有漏检把这些漏检挑出来人工补标是扩大数据集最节约时间的做法。流程是用训练好的权重遍历原始大图保存置信度在 0.1 到 0.5 之间的检测框转为 VOC 格式导入 lableimg 做人工修正。这个过程一般能找回 25% 左右的漏检框尤其是小目标。6.3 用统计脚本量化数据集的“难”在哪import os import numpy as np def analyze_bbox_size(txt_dir): all_areas [] all_wh [] for f in os.listdir(txt_dir): with open(os.path.join(txt_dir, f), r) as fh: for line in fh.readlines(): _, cx, cy, w, h map(float, line.strip().split()) # 归一化面积乘以输入分辨率得到实际像素面积 all_areas.append(w * h) all_wh.append((w, h)) all_areas np.array(all_areas) print(f框总数: {len(all_areas)}, 中位面积: {np.median(all_areas):.4f}) print(f面积小于 0.01 的框占比: {(all_areas 0.01).mean() * 100:.1f}%) analyze_bbox_size(labels/train)这个统计直接关系到训练策略小框占比高的时候把--img调到 1280 的收益远大于调大模型中位面积如果集中在 0.02 以下就需要考虑用 SAHI 或切图训练这类专门方案。从那以后我每次拿到新数据集都强制先跑一遍这个统计脚本再进训练循环省掉过无数轮“损失很漂亮但漏检一片”的无效训练。这套数据连同划分脚本和教程文档把这些步骤全部预置好了剩下的就是你自己的实验设计了。希望帮到你。本文还有配套的精品资源点击获取
返回列表