☰
无人机识别数据集:9229张图双格式标签,YOLO与VOC即用
2026/10/12 14:13:11 网站建设 项目流程

简介:这份资源是面向深度学习目标检测方向的无人机识别数据集,适合正在做无人机检测项目、课程设计或算法对比实验的研究者与开发者使用。数据集同时提供YOLO与VOC两种标注格式,可无缝接入YOLOv5至YOLOv10等YOLO系列算法,也能用于Faster R-CNN、SSD等模型的训练与验证,帮助使用者省去自行采集与标注的成本。压缩包内共2000个文件,以1999个txt标签文件和1个yaml类别配置文件为主,txt对应每张图片的目标框标注,yaml则指定类别信息与数据路径,整体约814.16MB,图片与标签已按训练集、验证集、测试集划分完毕,开箱即可投入训练。目前已有340人学习下载,配套博文对数据集细节做了进一步说明,便于快速了解类别分布与使用方式,适合作为无人机识别任务的基线数据或算法性能对比的统一评测集。

1. 无人机识别数据集:9229 张图、双格式标签,拿到手就能开训

做低空目标检测的同行大概都有过这种体验:模型结构调了一周,学习率换了三套,mAP 死活上不去,最后发现是数据集里一半的框标歪了。无人机识别这个方向尤其明显——目标小、背景杂、天上飞的鸟和四旋翼在低分辨率下几乎一个样,标注质量直接决定模型上限。这次拆的是一份无人机识别目标检测数据集,9229 张图,同时给了 YOLO 的 txt 标签和 VOC 的 xml 标签,还附带指定类别信息的 yaml 文件,图片和标签已经按训练集、验证集、测试集切好。换句话说,YOLOv5 到 YOLOv10 这一串算法,改个 data 路径就能直接跑,不用自己再写划分脚本。适合两类人:一类是想快速验证检测 pipeline 的工程同学,另一类是做鸟类目标检测、移动小目标检测、遥感目标检测,需要一份干净基线数据来对比实验的。下面按「这份数据长什么样 → 怎么接进 YOLO → 怎么接进 VOC 系 → 坑在哪 → 怎么验证训得对不对」的顺序拆开讲。

2. 数据集结构与格式解析:txt、xml、yaml 三件套怎么配合

2.1 目录组织与文件命名规律

从项目正文给出的文件名看,标签文件是Drone_1.txt、Drone_4235.txt、Drone_3936.txt这种「类别前缀 + 数字编号」的形式,编号不连续,说明它是从原始大池子里抽出来、重命名过的。这种命名方式有个好处:图片和标签靠同名对应,Drone_4235.jpg配Drone_4235.txt,不用维护额外的映射表。常见做法是把数据整理成下面这种结构,YOLO 系和 VOC 系都能兼容:

drone_dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── annotations/ # VOC 格式 xml │ ├── train/ │ ├── val/ │ └── test/ └── drone.yaml

这里要注意一点:YOLO 的 txt 和 VOC 的 xml 是两套坐标系。txt 是归一化的class cx cy w h,值都在 0~1 之间;xml 是绝对像素的xmin ymin xmax ymax。同一张图两种标签必须指向同一个目标框,否则你拿 txt 训完再用 xml 评估,数字对不上还以为是模型问题。我一般会抽 5~10 张图,把两种标签都画出来叠在原图上肉眼比对,确认框位置一致再往下走。

2.2 YOLO txt 标签格式与类别映射

YOLO 格式每行五个字段,第一个是类别索引,后四个是归一化坐标。假设这份数据只有「无人机」一个类,那类别索引就是 0。用 Python 快速校验一遍标签合法性的脚本如下:

import os import glob # 标签目录,按你的实际路径改 label_dir = "drone_dataset/labels/train" img_dir = "drone_dataset/images/train" bad_files = [] for txt_path in glob.glob(os.path.join(label_dir, "*.txt")): stem = os.path.splitext(os.path.basename(txt_path))[0] # 1. 检查是否有同名图片 img_exists = any( os.path.exists(os.path.join(img_dir, stem + ext)) for ext in [".jpg", ".jpeg", ".png"] ) if not img_exists: bad_files.append((txt_path, "no matching image")) continue # 2. 检查每行字段数与数值范围 with open(txt_path) as f: for line_no, line in enumerate(f, 1): parts = line.strip().split() if len(parts) != 5: bad_files.append((txt_path, f"line {line_no} field count {len(parts)}")) continue cls, cx, cy, w, h = parts vals = list(map(float, [cx, cy, w, h])) if any(v < 0 or v > 1 for v in vals): bad_files.append((txt_path, f"line {line_no} out of range {vals}")) if float(w) <= 0 or float(h) <= 0: bad_files.append((txt_path, f"line {line_no} zero size")) print(f"checked, bad count = {len(bad_files)}") for item in bad_files[:20]: print(item)

逻辑说明:先做「图片-标签」配对检查,再逐行验证字段数和归一化范围。参数上,label_dir和img_dir要指向同一划分(train 对 train),别交叉。w或h为 0 的框是典型的标注事故,训练时会被算成负样本,直接拖低召回。跑完如果bad count不为 0,先修数据再谈调参,这是血泪经验。

2.3 yaml 配置文件与 VOC xml 的用途

yaml 文件是 YOLO 系训练的入口,通常长这样:

path: ./drone_dataset train: images/train val: images/val test: images/test nc: 1 names: 0: drone

nc是类别数,names是索引到类名的映射,必须和 txt 里的类别索引严格对应。如果这份数据实际有多个类(比如无人机和鸟),nc和names要同步改,漏一个就会出现「训练不报错但类别全错」的玄学现象。VOC 的 xml 则主要给 Faster R-CNN、SSD 这类框架用,每个 xml 里包含filename、size、若干object(含name和bndbox)。用 xml 之前建议先统计一下所有name取值,确认没有拼写不一致(drone/Drone/UAV混用是常见坑)。

3. 接入 YOLOv5~YOLOv10:从环境到首轮训练

3.1 环境配置与依赖版本

YOLO 系现在主流走 Ultralytics 这一套,环境配置本身不复杂,坑主要在版本匹配。常见做法是建独立虚拟环境,Python 3.9~3.11 都行,torch 按显卡 CUDA 版本装。下面是一套通用流程:

# 1. 建环境 conda create -n drone_yolo python=3.10 -y conda activate drone_yolo # 2. 装 torch,按你的 CUDA 版本选,这里以 cu118 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 3. 装 ultralytics pip install ultralytics # 4. 验证 yolo checks

yolo checks会打印 torch、CUDA、设备信息,确认 GPU 被识别到再往下。如果这里显示 CPU,后面训练会慢到怀疑人生。参数上,--index-url里的 cu118 要换成你驱动支持的版本,装错了会出现「import torch 成功但 cuda.is_available() 为 False」。

3.2 用命令行启动首轮训练

数据按第 2 章的目录摆好、yaml 改好之后,一条命令就能起训:

yolo detect train \ data=drone_dataset/drone.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ project=runs/drone \ name=baseline

逐项说明:data指向 yaml;model用预训练权重,小目标场景建议从yolov8s起步,n太小吃不饱;imgsz=640是常规值,无人机目标偏小的话可以试 960 或 1280,但显存要跟上;batch=16按显存调,爆显存就减半;project和name决定结果落盘位置。首轮训练的目的不是刷高指标,而是确认整条链路通——loss 在降、验证集能出框、runs/drone/baseline/weights/best.pt能生成,这三件事齐了再谈调优。

3.3 用 Python API 做自定义评估

命令行跑通后,评估和推理建议用 Python API,方便接自己的后处理:

from ultralytics import YOLO # 加载训练好的权重 model = YOLO("runs/drone/baseline/weights/best.pt") # 在测试集上评估 metrics = model.val(data="drone_dataset/drone.yaml", split="test") print("mAP50:", metrics.box.map50) print("mAP50-95:", metrics.box.map) # 单图推理并保存可视化 results = model.predict("drone_dataset/images/test/Drone_4235.jpg", conf=0.25, save=True) for r in results: print("boxes:", r.boxes.xyxy.shape[0])

逻辑说明:val的split="test"确保用的是测试集而不是验证集,很多人默认跑 val 然后拿这个数字当最终指标,属于自欺欺人。conf=0.25是推理置信度阈值,评估阶段用默认即可,部署时再按业务调。r.boxes.xyxy.shape[0]能快速看单图检出数量,配合save=True出的可视化图,肉眼判断漏检和误检。

3.4 接入 Faster R-CNN / SSD 的 VOC 路径

如果要用 xml 训 Faster R-CNN 或 SSD,主流做法是转成 COCO 或直接读 VOC。以 torchvision 的 Faster R-CNN 为例,需要自己写 Dataset 读 xml:

import os import torch import xml.etree.ElementTree as ET from PIL import Image from torch.utils.data import Dataset class DroneVOCDataset(Dataset): def __init__(self, img_dir, ann_dir, transforms=None): self.img_dir = img_dir self.ann_dir = ann_dir self.transforms = transforms self.ids = [os.path.splitext(f)[0] for f in os.listdir(ann_dir) if f.endswith(".xml")] def __getitem__(self, idx): stem = self.ids[idx] img = Image.open(os.path.join(self.img_dir, stem + ".jpg")).convert("RGB") tree = ET.parse(os.path.join(self.ann_dir, stem + ".xml")) boxes, labels = [], [] for obj in tree.findall("object"): # 类别名到索引的映射,按你的 names 改 labels.append(0) 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) boxes.append([xmin, ymin, xmax, ymax]) target = { "boxes": torch.tensor(boxes, dtype=torch.float32), "labels": torch.tensor(labels, dtype=torch.int64), } if self.transforms: img = self.transforms(img) return img, target def __len__(self): return len(self.ids)

逻辑说明:ids从 xml 文件名反推,保证图片和标注配对;labels这里硬编码为 0,多类场景要按name查表。注意 torchvision 检测模型要求 boxes 是[xmin, ymin, xmax, ymax]绝对坐标,和 VOC 一致,所以不用像 YOLO 那样归一化。参数上,transforms里别加随机裁剪,小目标被裁掉就没了。

4. 避坑与排查:标注、划分、训练三类高频翻车

4.1 图片与标签数量对不上

现象:训练启动时报No labels found或某张图被跳过。原因:图片和标签文件名不一致,或者扩展名大小写不同(.JPGvs.jpg)。解决:跑第 2.2 节的校验脚本,把bad_files里的配对问题逐个修掉;批量重命名时统一转小写。

4.2 训练集和验证集出现同一目标

现象:验证集 mAP 高得离谱,换测试集直接掉十几个点。原因:划分时按图片随机切,但同一段视频抽帧的相似图被分到了 train 和 val,等于变相泄漏。解决:如果数据来自视频,按视频源或时间戳划分,而不是按帧随机;已经切好的这份数据,建议抽查 val 和 train 里有没有视觉上几乎一样的图。

4.3 类别索引与 names 错位

现象:训练不报错,但推理时框的位置对、类别名全错。原因:txt 里类别索引是 1,yaml 里names从 0 开始,或者多类数据里索引顺序和 names 不一致。解决:统计所有 txt 第一列的唯一值,和 yaml 的names键逐一对照,数量对不上就改 yaml。

4.4 小目标在 640 分辨率下消失

现象:大无人机能检出,远处小点全漏。原因:下采样后小目标特征被吞掉。解决:把imgsz提到 960 或 1280,或改用带 P2 检测头的模型配置;同时检查标注里有没有大量宽高小于 8 像素的框,这种框在 640 下基本学不到。

4.5 显存爆掉但 batch 已经很小

现象:batch=4还 OOM。原因:imgsz太大,或 dataloader 的workers开太多导致内存涨。解决:先降imgsz,再降workers,最后才动batch;用nvidia-smi实时看显存占用,别凭感觉调。

5. 验证与进阶:怎么确认这份数据真的训得动

训完一轮,别只看终端最后那行 mAP。我一般会走一套固定验证流程,确认模型和数据都正常。第一步,看训练曲线:runs/drone/baseline/results.png里 box_loss、cls_loss、mAP50 三条线,正常情况 loss 单调下降、mAP 单调上升,如果 loss 震荡剧烈,多半是学习率或 batch 问题。第二步,跑混淆矩阵:confusion_matrix.png能看出有没有把背景误判成目标,无人机场景里云、鸟、建筑边缘是主要干扰源。第三步,抽测试集里最难的一批图——目标最小、背景最杂的那些——单独推理,看漏检集中在什么尺度。

进阶用法上,这份数据同时有 txt 和 xml,很适合做格式转换的对照实验。比如把 xml 转成 YOLO txt,和自带的 txt 比对,能验证转换脚本的正确性:

import xml.etree.ElementTree as ET from PIL import Image def voc_to_yolo(xml_path, img_path, class_map): tree = ET.parse(xml_path) root = tree.getroot() w = int(root.find("size/width").text) h = int(root.find("size/height").text) lines = [] for obj in root.findall("object"): name = obj.find("name").text cls = class_map[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) # 转成归一化中心点 + 宽高 cx = (xmin + xmax) / 2 / w cy = (ymin + ymax) / 2 / h bw = (xmax - xmin) / w bh = (ymax - ymin) / h lines.append(f"{cls} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}") return "\n".join(lines) # 用法:class_map 按你的 names 建 cmap = {"drone": 0} print(voc_to_yolo("annotations/train/Drone_1.xml", "images/train/Drone_1.jpg", cmap))

逻辑说明:VOC 的绝对坐标除以图宽高得到归一化值,中心点用(xmin+xmax)/2算。参数上class_map必须和 yaml 的names一致,否则类别索引错位。转换完拿几张图和自带 txt 对比,数值对得上说明两套标签同源,对不上就要查是哪边标错了。

另一个值得做的验证是跨模型一致性:同一份数据,YOLOv8 和 Faster R-CNN 各训一版,如果两者 mAP 差距在合理范围内(通常 3~8 个点),说明数据本身没有系统性偏差;如果差出 20 个点,大概率是某一套标签格式没接对。这套交叉验证我踩过坑之后就一直保留,比单看一个模型的数字靠谱得多。

从那以后我每次拿到新数据集,都强制先跑一遍配对校验和标签范围检查,再抽图可视化比对,最后才开训。这三步花不了半小时,能省掉后面几天的无效调参。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询