
简介这份资源是面向无人机俯视视角目标检测任务的YOLO格式数据集适合从事车辆与行人检测的算法工程师、研究生及竞赛选手使用可直接用于yolov5、yolov7、yolov8等主流框架的模型训练与验证。压缩包共2000个文件包含1648个txt标注文件、351张jpg图像和1个yaml配置文件整体约850.13MB标注与图像一一对应覆盖car与person两个类别。数据集已按train、valid、test完成划分并附带data.yaml其中names为[car,person]各子集路径指向对应images目录开箱即可接入训练流程省去自行清洗与划分的繁琐工作。目前已有1681人学习下载说明其在无人机视觉场景中具备一定参考价值。借助该数据集读者可快速复现俯视视角下的车辆与行人检测实验对比不同YOLO版本的精度与速度表现并在此基础上调整anchor、数据增强策略或迁移至自有航拍数据是入门与进阶无人机目标检测的实用素材。1. 无人机俯拍下的车辆与行人检测为什么通用数据集一上机就翻车把 YOLOv5 直接套到无人机俯视场景十有八九第一轮验证就会给你泼冷水。地面监控数据集里行人占几十个像素、车辆横平竖直而无人机在 50 到 120 米高度俯拍时车辆变成巴掌大的矩形块行人只剩一个头顶加肩膀的椭圆点尺度、视角、遮挡关系全变了。vis-drone-yolov5-dataset-1.zip 这类数据集要解决的就是这个错位它把俯视视角下的车辆和行人单独标注出来让 YOLOv5 在无人机航拍域里重新收敛。这篇笔记面向已经跑通过 YOLOv5 官方 COCO 流程、准备把模型搬到无人机视觉感知链路上的工程师从数据集结构、标签格式转换、训练参数到部署量化把能复现的步骤和踩过的坑一次讲清。如果你正在做无人机航拍工地巡检、交通流量统计或者移动小目标检测这套流程可以直接照搬。2. 拆开 vis-drone-yolov5-dataset-1.zip目录结构、标签格式与类别定义拿到一个无人机俯视数据集先别急着写训练脚本。我一般会花二十分钟把压缩包解干净用tree和几行 Python 把目录、图片尺寸、标签分布摸一遍。这一步决定了后面要不要做格式转换、要不要重设 anchor、要不要按高度分层采样。vis-drone-yolov5-dataset-1.zip 从命名看是面向 YOLOv5 的无人机视觉数据集常见组织方式是 images/labels 双目录加 data.yaml但不同来源的包差异很大必须实测确认。2.1 解压后先跑一遍目录体检# 解压到独立目录避免污染其他数据集 mkdir -p ~/datasets/vis_drone cd ~/datasets/vis_drone unzip ~/downloads/vis-drone-yolov5-dataset-1.zip -d . # 看顶层结构确认是 images/labels 还是 train/val 分目录 find . -maxdepth 2 -type d | sort # 统计图片数量与格式 find . -type f \( -name *.jpg -o -name *.png -o -name *.jpeg \) | wc -l find . -type f -name *.jpg | head -5这段命令做三件事确认解压后的目录层级、统计图片总量、抽样看文件命名规律。如果输出里出现images/train、images/val、labels/train、labels/val四组目录说明数据集已经按 YOLOv5 标准切分好如果只有扁平的images和labels就需要自己写切分脚本。图片格式优先看是不是 jpgpng 会拖慢 dataloader必要时批量转 jpg。2.2 用 Python 核对标签与类别import os, glob from collections import Counter root os.path.expanduser(~/datasets/vis_drone) label_files glob.glob(os.path.join(root, **, *.txt), recursiveTrue) # 过滤掉 data.yaml 之类的非标签文件YOLO 标签每行至少 5 列 label_files [f for f in label_files if os.path.basename(f) ! data.yaml] cls_counter Counter() box_areas [] for lf in label_files: with open(lf) as f: for line in f: parts line.strip().split() if len(parts) ! 5: continue c, x, y, w, h int(parts[0]), *map(float, parts[1:]) cls_counter[c] 1 box_areas.append(w * h) # 归一化面积用于判断小目标占比 print(类别分布:, dict(cls_counter)) print(标签文件数:, len(label_files)) print(目标框总数:, sum(cls_counter.values())) print(平均归一化面积:, sum(box_areas) / len(box_areas)) print(面积小于 0.001 的框占比:, sum(1 for a in box_areas if a 0.001) / len(box_areas))逻辑说明YOLO 标签每行是class x_center y_center width height全部归一化到 0 到 1。cls_counter告诉你类别是否平衡无人机数据集常见问题是行人样本远少于车辆。box_areas用来量化小目标比例归一化面积小于 0.001 基本就是俯拍小目标后面 anchor 和输入分辨率都要围绕它调。参数上如果类别只有 0 和 1data.yaml 里nc: 2names: [vehicle, pedestrian]顺序必须和标签里的 class id 严格对应错一位整个训练就废了。2.3 data.yaml 与类别映射的确认# data.yaml 常见写法路径按实际解压位置改 path: /home/user/datasets/vis_drone train: images/train val: images/val nc: 2 names: [vehicle, pedestrian]如果压缩包里没有 data.yaml就按上面模板自己建。path用绝对路径最稳相对路径在 YOLOv5 不同版本里解析基准不一致容易翻车。names的顺序不是随便写的它对应标签文件里的 class id0 对应列表第一个。改完用python -c import yaml; print(yaml.safe_load(open(data.yaml)))验证一遍语法YAML 缩进错一格就会静默读成 None。3. 用 YOLOv5 在本地跑通无人机数据集的最小训练命令数据集体检完下一步是让训练真正跑起来。YOLOv5 的仓库结构、依赖安装网上资料很多这里只讲和无人机俯视数据强相关的部分输入分辨率、anchor 重聚类、batch 与显存的关系。很多人直接拿默认--img 640开跑结果小目标召回率惨不忍睹问题就出在分辨率没跟着目标尺度走。3.1 环境与依赖的快速确认git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt # 验证 torch 和 cuda 是否可用 python -c import torch; print(torch.__version__, torch.cuda.is_available())这段是标准起手式。torch.cuda.is_available()返回 False 时先别怀疑代码检查显卡驱动和 CUDA 版本匹配。YOLOv5 对 torch 版本比较宽容但 2.x 和 1.x 在部分算子上有差异团队协作时把版本写进 requirements 锁死。无人机数据集图片分辨率通常较高dataloader 的--workers建议设成 CPU 核数的 0.7 倍左右设太高反而因为 IO 争抢变慢。3.2 针对俯视小目标重聚类 anchor# 用训练集标签重新聚类 anchork 设为 9 对应 3 个尺度各 3 个 anchor python utils/autanchor.py --data data.yaml --img-size 960 --thr 4.0 --n 9逻辑说明autanchor.py会读取 data.yaml 指向的训练标签用 k-means 聚出 9 组宽高。无人机俯拍目标普遍偏小且长宽比接近 1:1默认 COCO anchor 偏大直接套用会导致正样本匹配过少。--img-size要和后面训练用的分辨率一致--thr是 anchor 与目标框的宽高比阈值俯视场景建议放宽到 4.0。跑完把输出的 anchor 写进模型配置文件或者训练时用--anchors指定。参数改完记得重新生成一次别用缓存。3.3 最小可跑训练命令与参数解释python train.py \ --data data.yaml \ --weights yolov5s.pt \ --img 960 \ --batch 16 \ --epochs 100 \ --hyp data/hyps/hyp.scratch-low.yaml \ --workers 8 \ --project runs/drone \ --name exp1逐参数说明--img 960是俯视小目标的关键640 下行人可能只剩 8 像素960 能保留更多细节代价是显存翻倍batch 要相应下调。--batch 16是 8G 显存跑 960 分辨率的保守值显存够可以上 24 或 32。--hyp选 low 增强版本无人机俯拍本身视角变化有限过强的 mosaic 和 mixup 反而引入不真实样本low 版本更稳。--weights yolov5s.pt用预训练权重加速收敛如果类别和 COCO 差异极大也可以从 scratch 开始但收敛慢很多。训练启动后盯前 10 个 epoch 的mAP0.5和box_loss如果 loss 不降先查标签路径和类别映射而不是调学习率。4. 无人机俯视检测的避坑与排查五条血泪记录这一章全是踩过的坑每条按现象、原因、解决写。无人机数据集和通用数据集最大的区别在于视角和尺度很多在 COCO 上不是问题的地方在这里会集中爆发。4.1 现象mAP 卡在 0.1 不动loss 缓慢下降原因标签类别顺序和 data.yaml 的 names 不一致或者图片和标签文件名没对上。YOLOv5 对缺失标签的图片会当负样本处理如果一半图片找不到标签模型学到的全是背景。解决写脚本核对 images 和 labels 的文件名 stem 是否一一对应用diff (ls images/train | sed s/\..*// | sort) (ls labels/train | sed s/\..*// | sort)快速定位。类别顺序用 2.2 的脚本打印确认。4.2 现象验证集 mAP 正常实际无人机视频推理全是漏检原因训练集和验证集来自同一批航拍片段分布太接近模型没学到跨高度、跨光照的泛化能力。解决按飞行高度或光照条件分层切分数据集而不是随机切。如果数据集本身没标注高度用图片的 EXIF 或文件名里的高度信息分组保证验证集包含训练时没见过的飞行高度。这一步在数据准备阶段做训练开始后就来不及了。4.3 现象训练到 50 epoch 后显存溢出原因YOLOv5 的 dataloader 在长训练中会累积缓存加上无人机图片分辨率高显存碎片化。解决把--workers降到 4加--noval每隔几个 epoch 再验证或者用torch.cuda.empty_cache()在自定义回调里定期清理。更彻底的办法是降低--img到 800配合更小的 anchor精度损失有限但显存稳定。4.4 现象小目标召回率极低大目标正常原因anchor 没重聚类默认 anchor 匹配不到小目标或者--img太小小目标在下采样后信息丢失。解决按 3.2 重聚类 anchor把--img提到 960 或 1280。如果显存不够用--rect矩形训练减少 padding或者把模型换成 yolov5m 增加容量。注意提高分辨率后要同步调大--batch的梯度累积步数保持等效 batch size。4.5 现象推理速度在边缘设备上只有个位数 FPS原因直接用 PyTorch 权重在 Jetson 或 RK3568 上跑没做量化和图优化。解决先导出 ONNX再用 TensorRT 或 RKNN 工具链量化。YOLOv5 官方export.py支持--include onnx导出时--img和--batch要和部署一致。量化后 mAP 通常掉 1 到 3 个点用验证集重新测一遍掉太多就改用 FP16 而不是 INT8。5. 从训练到部署量化、验证与一个提点技巧训练收敛只是上半场无人机视觉感知的落地瓶颈在边缘端推理。这一章讲怎么把 vis-drone-yolov5-dataset-1.zip 训出来的模型压到能上机的程度以及一个我常用的验证技巧。5.1 导出 ONNX 与量化验证# 导出 ONNXopset 12 兼容性最好 python export.py --weights runs/drone/exp1/weights/best.pt --include onnx --img 960 --batch 1 --opset 12 # 用 onnxruntime 验证导出模型和原模型输出一致性 python -c import onnxruntime as ort, numpy as np sess ort.InferenceSession(best.onnx) x np.random.randn(1, 3, 960, 960).astype(np.float32) out sess.run(None, {sess.get_inputs()[0].name: x}) print(输出形状:, [o.shape for o in out]) 逻辑说明--opset 12是 TensorRT 和 RKNN 都支持的版本opset 太高部分工具链不认。--batch 1是边缘部署的常见 batch导出时 batch 维度固定后面改起来麻烦。onnxruntime 验证这一步别省导出过程可能因为自定义算子静默出错输出形状对不上就说明导出有问题。参数上如果部署平台支持动态 batch导出时用--dynamic但会牺牲部分推理速度。5.2 用视频抽帧做端到端验证import cv2, torch model torch.hub.load(ultralytics/yolov5, custom, pathruns/drone/exp1/weights/best.pt) model.conf 0.35 # 俯视小目标置信度阈值适当降低 model.iou 0.45 cap cv2.VideoCapture(drone_flight.mp4) frame_id 0 while cap.isOpened(): ret, frame cap.read() if not ret: break if frame_id % 10 0: # 每 10 帧抽一帧降低验证成本 results model(frame) results.save(save_dirruns/verify) frame_id 1 cap.release()这段脚本把训练好的模型直接套到无人机视频上conf设 0.35 是因为俯视小目标得分普遍偏低设 0.5 会漏掉大量行人。iou0.45 是 NMS 阈值俯拍车辆密集时适当调低能减少漏检。每 10 帧抽一帧是为了快速看整体效果正式验证要逐帧跑并统计。验证时重点看三类失败小目标漏检、密集场景粘连、运动模糊导致的误检。5.3 一个提点技巧按目标尺度分层评估我习惯在验证阶段把目标按归一化面积分成小、中、大三档分别统计 mAP。YOLOv5 默认只给整体 mAP俯视场景里小目标才是关键整体 mAP 会被大目标拉高掩盖小目标的糟糕表现。做法是在验证脚本里加一个按面积分桶的统计面积小于 0.001 算小目标0.001 到 0.01 算中大于 0.01 算大。如果小目标 mAP 比整体低 20 个点以上说明分辨率或 anchor 还有优化空间。这个习惯帮我省了很多次盲目调参的时间也让我在交付前能明确告诉团队模型的能力边界。希望帮到你。本文还有配套的精品资源点击获取