首页
/ VisDrone 无人机小目标检测数据集在 YOLO26 中的完整训练实践:自动下载、YOLO 格式转换与配置解析

VisDrone 无人机小目标检测数据集在 YOLO26 中的完整训练实践:自动下载、YOLO 格式转换与配置解析

2026-09-04 09:18:08作者:彭桢灵Jeremy

本文以 Ultralytics 官方文档 VisDrone 数据集页 为主体,系统讲解如何使用 data="VisDrone.yaml" 一键训练 YOLO26 检测模型。读完你可以掌握:VisDrone-DET 数据集的构成与划分(8,629 张航拍图像、10 个类别)、VisDrone.yaml 的完整字段与自动下载/标注转换脚本的逐行解析、底层自动下载机制在源码中的真实调用链,以及针对航拍小目标场景的训练调优建议(高分辨率、SAHI 切片推理)。

一、数据集概览:为什么 VisDrone 是小目标检测的标准基准

VisDrone 是由中国天津大学机器学习与数据挖掘实验室(MLDM)的 AISKYEYE 团队构建并维护的大规模无人机影像基准。完整基准包含在中国 14 个城市用机载相机采集的 288 段视频(共 261,908 帧)和 10,209 张静态图像,覆盖城市与乡村环境、稀疏与拥挤场景、多种天气与光照条件。全部帧累计带有 超过 260 万个手工标注边界框,并附带场景可见性、物体类别、遮挡程度等额外属性。

Ultralytics 仓库中的 VisDrone.yaml 配置只使用其中用于目标检测的 VisDrone2019-DET 静态图像子集,该子集提供 8,629 张航拍图像,全部划分为固定的 train / val / test-dev 三部分:

划分 图像数 用途
Train 6,471 用于训练检测器
Validation 548 开发阶段的验证
Test-dev 1,610 训练完成后做最终评测

此外还存在第四个划分 test-challenge(1,580 张),它被 VisDrone 竞赛扣留、不随下载脚本分发——这也是完整的 DET 集合总数为 10,209 张图像的原因。

1.1 关键特征

  • 小而密的物体:航拍视角使目标又小又密集——仅 548 张验证图像就包含 38,759 个标注框,平均约 70 个物体/图。
  • 场景多样性:来自 14 个中国城市,覆盖城市/乡村、白天/夜晚、不同天气。
  • 标注丰富:全基准超过 260 万个框,且带遮挡(occlusion)与可见性(visibility)属性。
  • 固定划分:train / val / test-dev(6,471 / 548 / 1,610)划分固定,便于一致性评测。

1.2 十个目标类别

数据集标注 10 个类别,与 VisDrone.yaml 中的 names 完全一致:

索引 类别 说明
0 pedestrian 站立或行走的行人
1 people 其他姿态的人
2 bicycle 自行车
3 car 小汽车
4 van 厢式车
5 truck 卡车
6 tricycle 三轮车
7 awning-tricycle 带篷三轮车
8 bus 公共汽车
9 motor 摩托车

注意 VisDrone 刻意区分 pedestrian(站立或行走的人)与 people(任何其他姿态的人),这两类的正确区分也是训练时需要关注的易混淆点。

二、Ultralytics 的 VisDrone.yaml 配置全解

Ultralytics 在 ultralytics/cfg/datasets/VisDrone.yaml 中维护该数据集的完整配置,包含三部分:路径定义、类别名、以及一段自动下载并转换为 YOLO 格式的 Python 脚本。

2.1 数据集目录结构与主配置

文件头部注释说明了下载后的目录约定:

# parent
# ├── ultralytics
# └── datasets
#     └── VisDrone ← downloads here (~2 GB)

核心路径配置(相对于 path 的相对路径)为:

path: VisDrone # dataset root dir
train: images/train # train images (relative to 'path') 6471 images
val: images/val # val images (relative to 'path') 548 images
test: images/test # test-dev images (optional) 1610 images

train / val / test 支持三种形式:目录(path/to/imgs)、图像清单文件(path/to/imgs.txt)、目录列表,此处均为目录。注释中的 6471 images548 images1610 images 与上表的划分规模一一对应。

2.2 自动下载与 YOLO 转换脚本

download: 字段内嵌了一段可直接执行的 Python 脚本,是理解“首次训练自动下载”的关键。其核心函数 visdrone2yolo 负责格式转换:

def visdrone2yolo(dir, split, source_name=None):
    """Convert VisDrone annotations to YOLO format with images/{split} and labels/{split} structure."""
    from PIL import Image

    source_dir = dir / (source_name or f"VisDrone2019-DET-{split}")
    images_dir = dir / "images" / split
    labels_dir = dir / "labels" / split
    labels_dir.mkdir(parents=True, exist_ok=True)

    # Move images to new structure
    if (source_images_dir := source_dir / "images").exists():
        images_dir.mkdir(parents=True, exist_ok=True)
        for img in source_images_dir.glob("*.jpg"):
            img.rename(images_dir / img.name)

    for f in TQDM((source_dir / "annotations").glob("*.txt"), desc=f"Converting {split}"):
        img_size = Image.open(images_dir / f.with_suffix(".jpg").name).size
        dw, dh = 1.0 / img_size[0], 1.0 / img_size[1]
        lines = []

        with open(f, encoding="utf-8") as file:
            for row in [x.split(",") for x in file.read().strip().splitlines()]:
                if row[4] != "0":  # Skip ignored regions
                    x, y, w, h = map(int, row[:4])
                    cls = int(row[5]) - 1
                    # Convert to YOLO format
                    x_center, y_center = (x + w / 2) * dw, (y + h / 2) * dh
                    w_norm, h_norm = w * dw, h * dh
                    lines.append(f"{cls} {x_center:.6f} {y_center:.6f} {w_norm:.6f} {h_norm:.6f}\n")

        (labels_dir / f.name).write_text("".join(lines), encoding="utf-8")

结合 VisDrone.yaml 的源码,转换逻辑有三个要点:

  1. 跳过被忽略的区域:VisDrone 原始标注每行是 x1,y1,w,h,ignored,cls,occlusion,truncation 的 CSV 格式,脚本以 row[4] != "0" 判断,凡 ignored 字段非 0 的框一律丢弃(这同时排除了未被使用的 "others" 类别)。
  2. 类别索引下移一位:VisDrone 原始类别编号从 1 开始,脚本用 cls = int(row[5]) - 1 映射到 YOLO 从 0 开始的 10 个类别。
  3. YOLO 归一化:先由 PIL 读取真实图像尺寸得到 dw, dh = 1/W, 1/H,再计算中心点与归一化宽高((x + w/2) * dw 等),输出标准五元组 cls xc yc w h(保留 6 位小数),文件写入 labels/{split}/,与 images/{split}/ 同名对应。

下载主流程则按“train → val → test-dev”三个压缩包顺序处理,刻意注释掉了 test-challenge 包:

# Download (ignores test-challenge split)
dir = Path(yaml["path"])  # dataset root dir
urls = [
    f"{ASSETS_URL}/VisDrone2019-DET-train.zip",
    f"{ASSETS_URL}/VisDrone2019-DET-val.zip",
    f"{ASSETS_URL}/VisDrone2019-DET-test-dev.zip",
    # f"{ASSETS_URL}/VisDrone2019-DET-test-challenge.zip",
]
download(urls, dir=dir, threads=4)

# Convert
splits = {"VisDrone2019-DET-train": "train", "VisDrone2019-DET-val": "val", "VisDrone2019-DET-test-dev": "test"}
for folder, split in splits.items():
    visdrone2yolo(dir, split, folder)  # convert VisDrone annotations to YOLO labels
    shutil.rmtree(dir / folder)  # cleanup original directory

可以看到:下载完成后脚本对每个划分先转换标注,再用 shutil.rmtree 删除原始 VisDrone2019-DET-* 目录,最终只保留干净的 images/ + labels/ 双目录结构。

三、源码级机制:自动下载是如何被触发的

“首次训练自动下载”并非魔法,其调用链在 ultralytics/data/utils.pycheck_det_dataset() 中实现。关键流程如下:

  1. 定位 YAML:传入 data="VisDrone.yaml" 后,check_file 会先在包内 ultralytics/cfg/datasets/ 目录中找到该文件;甚至允许直接传裸名(如 data="VisDrone"),源码会自动尝试补全为 .yaml/.ymlutils.py L567-L569)。
  2. 校验必填字段:函数强制要求 YAML 中存在 trainval 键,且 namesnc 至少提供一个(L590-L617)——VisDrone.yaml 的 10 类 names 即在此通过校验,nc 被自动推导为 10。
  3. 路径解析path: VisDrone 是相对路径,源码会将其解析到全局数据集目录 DATASETS_DIR 之下(L623-L625)。DATASETS_DIR 取自用户设置项 SETTINGS["datasets_dir"],定义在 ultralytics/utils/init.py,默认位于 ultralytics 仓库同级目录的 datasets/ 下。
  4. 执行 download 脚本:当 val 指向的图像目录尚不存在且 autodownload 开启时,源码按 download 字段的值分派执行策略——以 http 开头且以 .zip 结尾的直接下载、以 bash 开头的走 shell 脚本,否则按 Python 脚本用 exec(s, {"yaml": data}) 执行(L654-L660)。这解释了为什么 VisDrone.yaml 的脚本体内可以直接使用变量 yaml(如 Path(yaml["path"]))——它是被注入的执行上下文。
  5. 镜像源与并发:三个压缩包均从 ASSETS_URL 拉取,该常量定义为 GitHub release 资产地址,见 ultralytics/utils/init.py L66download(urls, dir=dir, threads=4) 以 4 线程并发下载,脚本执行完毕后源码会打印形如 Dataset download success ✅ (xx.xs) 的日志(L661-L663)。

因此整条链路可以概括为:model.train(data="VisDrone.yaml")check_det_dataset 发现 datasets/VisDrone/images/val 不存在 → exec 内嵌下载脚本 → 下载约 2 GB 的三个 zip → visdrone2yolo 转成 YOLO 标签 → 清理原始目录 → 训练继续

四、训练实操:一键训练 YOLO26 检测模型

4.1 资源与空间预算

  • 首次训练会自动下载 3 个压缩包,共约 2 GB
  • 解压并转换过程中大约需要 4 GB 空闲磁盘空间

4.2 训练代码

以 YOLO26n 为例,在 VisDrone 上训练 100 个 epoch、图像尺寸 640:

Python 方式(数据集在首次运行时自动下载并转换):

from ultralytics import YOLO

# Load a model
model = YOLO("yolo26n.pt")  # load a pretrained model (recommended for training)

# Train the model - dataset will auto-download on first run
results = model.train(data="VisDrone.yaml", epochs=100, imgsz=640)

CLI 方式

# Start training from a pretrained *.pt model
# Dataset will auto-download and convert on first run
yolo detect train data=VisDrone.yaml model=yolo26n.pt epochs=100 imgsz=640

完整的训练参数(batchpatienceamp、增强选项等)请参考官方训练文档

4.3 小目标精度调优建议

VisDrone 的困难在于物体相对画面极小(往往只有几十个像素),且常以密集、重度遮挡的群组出现,这使得在地面视角照片上调参的检测器直接迁移时会显著掉点。针对该数据集有两个被官方文档推荐的改进方向:

  • 提高训练/推理分辨率:例如将 imgsz 提到 1280 并适当减小 batch size,小目标就能在特征图上占据更多像素,从而被更完整地检测;
  • SAHI 切片推理SAHI 瓦片化推理将大图切成多个窗口分别推理再合并结果,让每个推理窗口中小目标占比更高,适合大尺寸航拍图的推理阶段。更多通用建议见模型训练技巧

五、典型应用场景与相关数据集

VisDrone 的密集场景与微小目标使其成为航拍视角小目标检测的标准基准,常见应用包括:

  • 无人机交通监控与车辆计数
  • 人群分析与公共安全监控
  • 基础设施与施工现场巡检
  • 杂乱场景中检测微小目标的计算机视觉研究

如果还有其他遥感/航拍基准需要对比,可以参考面向卫星影像的 xView 数据集(小目标同样突出)以及采用有向框标注的 DOTA-v2 数据集

六、常见问题(FAQ)

Q1:VisDrone 能用于什么? 在无人机影像上训练和评测检测器——目标小、密集、俯视拍摄。其航拍视角、拥挤场景与多变条件的组合,使它成为 UAV 交通监控、人群分析和微小目标研究的常用测试床。

Q2:图像与类别数量? Ultralytics 配置包含 8,629 张图像(6,471 训练 / 548 验证 / 1,610 test-dev),全部共享同样 10 个类别:pedestrian、people、bicycle、car、van、truck、tricycle、awning-tricycle、bus、motor。

Q3:如何下载?data="VisDrone.yaml" 首次训练时自动下载,无需手动操作。脚本从 Ultralytics 的 release 资产地址抓取约 2 GB 的三个压缩包,并把标注转换为 YOLO 格式;竞赛扣留的 test-challenge 划分不包含在内。

Q4:VisDrone-DET 与完整 VisDrone 基准的区别? 完整基准覆盖 5 项任务——图像检测、视频检测、单目标跟踪、多目标跟踪和人群计数,共 288 段视频与 10,209 张静态图像。Ultralytics 的 VisDrone.yaml 只覆盖图像检测任务(VisDrone2019-DET),即 6,471 / 548 / 1,610 三部分。

Q5:为什么检测器在 VisDrone 上表现差,怎么提升? 对象在画面中往往只有几十个像素且密集遮挡。如前所述,提高 imgsz(如 1280)配合更小的 batch,以及推理阶段使用 SAHI 切片,是两条有效的路径。

七、引用与致谢

若在研究中使用 VisDrone 数据集,请引用以下论文:

@ARTICLE{9573394,
  author={Zhu, Pengfei and Wen, Longyin and Du, Dawei and Bian, Xiao and Fan, Heng and Hu, Qinghua and Ling, Haibin},
  journal={IEEE Transactions on Pattern Analysis and Machine Intelligence},
  title={Detection and Tracking Meet Drones Challenge},
  year={2022},
  volume={44},
  number={11},
  pages={7380-7399},
  doi={10.1109/TPAMI.2021.3119563}}

感谢中国天津大学机器学习与数据挖掘实验室的 AISKYEYE 团队创建并持续维护 VisDrone 数据集。

小结

  • 一份 YAML 搞定数据接入ultralytics/cfg/datasets/VisDrone.yaml 把路径、10 类 names 和内嵌下载/转换脚本合为一体,data="VisDrone.yaml" 即可启动训练。
  • 转换逻辑值得细读:跳过 ignored 区域、类别编号减一、按真实图像尺寸归一化,三步完成 VisDrone 原始 CSV 到 YOLO 五元组的转换。
  • 机制可溯源:自动下载由 check_det_dataset 在验证集目录缺失时 exec 触发,下载源为 ASSETS_URLutils/__init__.py),数据集落地于 DATASETS_DIRutils/__init__.py L1527)。
  • 针对小目标调优:提高 imgsz 与 SAHI 切片推理是文档给出的两条提升航拍小目标召回率的主线。
登录后查看全文
热门项目推荐
相关项目推荐