简介这份资源面向无人机场景下的车辆检测任务提供1000张真实场景高质量图片覆盖城市道路行驶车辆、道边停车、停车场、小区车辆以及车辆遮挡、严重遮挡等多种情形类别划分为轿车car、货车van和巴士bus三类适合目标检测项目实战与通用车辆检测数据补充。资源包为1个PDF文件约2MB内附数据集基本情况介绍与获取方式并说明提供VOC(xml)、COCO(json)、YOLO(txt)三种常见标注格式可直接用于YOLO等算法训练。随附YOLO11一键训练脚本支持GPU(GPUs)、CPU及Mac(M芯片)多平台方案并给出博主训练结果日志供参考。目前已有261人学习下载适合需要快速搭建无人机车辆检测训练流程、验证多格式标签兼容性与跨平台训练可行性的开发者与研究者。1. 无人机车辆检测数据集1000 张图、三种标签格式与 YOLO11 一键训练到底怎么落地拿到「无人机场景-目标检测-车辆检测数据集-1000张图-对应VOC/COCO/YOLO三种格式标签支持GPU(GPUs)/CPU/Mac三平台YOLO11一键训练脚本」这个标题很多人第一反应是「数据集而已下载解压就能训」。真上手才发现坑全在细节里无人机视角的车辆目标又小又密VOC 的 XML 和 YOLO 的 txt 对不上号脚本在 GPU 机器上跑得飞起换到 Mac 的 M 系列芯片直接报 device 错误。这篇笔记就按一线落地的顺序把这份数据集从「是什么」讲到「怎么训、怎么排错、怎么验证」让新手能照着命令走完熟手能看清参数边界和踩坑点。适合做无人机视觉感知、小目标检测、边缘端车辆识别的从业者也适合手里只有一张消费级显卡、想先跑通 YOLO11 全流程的人。2. 先搞清楚这份数据集的结构与三种标签格式的对应关系2.1 1000 张无人机图为什么值得单独做一份数据集无人机视角和地面监控视角完全是两回事。地面摄像头高度固定、俯仰角小车辆在画面里通常是中大型目标无人机航拍高度动辄几十米到上百米俯仰角接近垂直或大倾角一辆车在 1080P 画面里可能只占 20×15 像素属于典型的小目标检测场景。这也是「小目标检测」这个词在无人机领域被反复提的原因——通用 COCO 预训练模型直接拿来用召回率往往掉得很难看。1000 张图这个量级说大不大说小也不小。它不足以从头训一个 backbone但足够做微调fine-tune尤其是配合 YOLO11 这种在 COCO 上预训练过的模型。实际项目里我一般把这类数据集定位成「领域适配集」用通用权重打底用这 1000 张把模型拉到无人机视角的分布上。数量上要清醒1000 张如果场景单一比如全是同一片停车场、同一种光照训出来的模型泛化会很差如果覆盖了不同高度、不同时段、不同背景那价值就高得多。所以拿到数据集第一件事不是急着训是先抽样看分布。三种标签格式并存是这份数据集的核心卖点也是最容易出问题的地方。VOC 是 XML一个图对应一个 XML框用 xmin/ymin/xmax/ymax 的绝对像素坐标COCO 是一个大的 JSON所有图的标注集中在一起框用 [x, y, width, height] 绝对坐标加 category_idYOLO 是每图一个 txt每行class cx cy w h全部归一化到 0~1。三者描述的是同一批框但坐标系、文件组织、类别索引规则都不同。训练 YOLO11 用的是 YOLO 格式所以转换和理解对应关系是绕不开的一步。2.2 三种格式的字段对照与转换时的坐标陷阱先把三种格式的字段摊开对比心里有张表转换时就不会晕。维度VOC (XML)COCO (JSON)YOLO (txt)文件组织每图一个 xml单个 json 汇总每图一个 txt框表示xmin,ymin,xmax,ymaxx,y,width,heightcx,cy,w,h坐标类型绝对像素绝对像素归一化 0~1类别name 字符串category_id 整数class 整数索引类别起点无固定常见从 1 开始从 0 开始坐标陷阱主要出在两个地方。第一VOC 转 YOLO 时cx (xmin xmax) / 2 / Ww (xmax - xmin) / W这里的 W、H 必须是该图真实的宽高不能想当然用 1920×1080。无人机图经常被裁剪或缩放尺寸五花八门写死尺寸是血泪教训。第二COCO 的 category_id 常常不是从 0 连续开始的比如只有 id3 的 car转 YOLO 时必须重映射成从 0 开始的连续索引否则训练时类别数对不上loss 直接 NaN。下面这段脚本把 VOC 转成 YOLO关键点都写在注释里。import os import xml.etree.ElementTree as ET from PIL import Image # 类别名到索引的映射必须固定顺序训练和推理要一致 CLASSES [car, truck, bus, van] CLASS_TO_ID {c: i for i, c in enumerate(CLASSES)} def voc_to_yolo(xml_dir, img_dir, out_dir): os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(xml_dir, xml_file)) root tree.getroot() # 用真实图片尺寸不要写死 img_name root.find(filename).text img_path os.path.join(img_dir, img_name) W, H Image.open(img_path).size lines [] for obj in root.iter(object): name obj.find(name).text.strip() if name not in CLASS_TO_ID: continue # 忽略未定义类别避免索引错乱 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 min(max((xmin xmax) / 2 / W, 0), 1) cy min(max((ymin ymax) / 2 / H, 0), 1) w min(max((xmax - xmin) / W, 0), 1) h min(max((ymax - ymin) / H, 0), 1) lines.append(f{CLASS_TO_ID[name]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) out_name os.path.splitext(xml_file)[0] .txt with open(os.path.join(out_dir, out_name), w) as f: f.write(\n.join(lines))逻辑说明遍历 XML逐 object 取框用真实图片尺寸归一化类别通过固定映射表转成从 0 开始的索引。参数说明CLASSES的顺序一旦定下就不能改训练配置里的names必须和它完全一致min(max(...))的裁剪是为了处理标注越界的脏数据无人机图里框超出画面边缘很常见。COCO 转 YOLO 思路类似区别是先读一个大 JSON按 image_id 分组再逐图写 txtcategory_id 要做一次重映射。2.3 划分训练集验证集与 data.yaml 的写法YOLO11 训练靠一个data.yaml描述数据位置和类别。目录结构我一般这样组织dataset/ images/ train/ val/ labels/ train/ val/ data.yaml划分比例 8:2 是常规做法但无人机数据要按场景划分而不是随机划分——同一段视频抽出来的帧如果同时进了 train 和 val验证指标会虚高这是很多人翻车的地方。data.yaml内容如下path: /abs/path/to/dataset train: images/train val: images/val names: 0: car 1: truck 2: bus 3: vanpath用绝对路径最稳相对路径在不同工作目录下容易找不到。names的索引必须和转换脚本里的CLASS_TO_ID一一对应错一位整个训练就废了。3. YOLO11 一键训练脚本在三平台上的实际跑法3.1 GPU、CPU、Mac 三平台的设备选择逻辑标题里强调「支持 GPU/CPU/Mac 三平台」本质是解决一个现实问题不是每个人都有多卡服务器很多人手里是 Windows 台式机带一张消费级卡或者 MacBook。YOLO11 基于 Ultralytics 框架设备选择靠device参数逻辑很直接NVIDIA GPUdevice0或device0,1走 CUDA速度最快。纯 CPUdevicecpu能跑但慢1000 张图训几十个 epoch 可能要几小时到十几小时。MacApple Silicondevicemps走 Metal Performance Shaders比 CPU 快不少但部分算子支持不完整偶尔会报错回退。一键脚本的核心就是自动探测设备避免用户手动改。下面是一个可复用的训练脚本骨架。import torch from ultralytics import YOLO def pick_device(): # 优先 CUDA其次 Apple MPS最后 CPU if torch.cuda.is_available(): return 0 if torch.backends.mps.is_available(): return mps return cpu def train(data_yaml, epochs100, imgsz640, batch16): device pick_device() print(fusing device: {device}) model YOLO(yolo11n.pt) # 预训练权重微调起点 model.train( datadata_yaml, epochsepochs, imgszimgsz, batchbatch, devicedevice, patience20, # 20 轮无提升就早停 workers4, projectruns/drone_car, nameexp1, ) if __name__ __main__: train(dataset/data.yaml)逻辑说明pick_device按 CUDA → MPS → CPU 的优先级返回设备字符串这是三平台兼容的关键。参数说明imgsz640是 YOLO11 的常用输入尺寸无人机小目标如果特别小可以提到 1280但显存和速度代价明显batch在 GPU 上可以给 16 或 32CPU 和 Mac 上建议降到 4 或 8否则内存吃紧patience20是早停防止过拟合空跑。yolo11n.pt是 nano 版本参数量小、速度快适合先跑通追求精度可以换yolo11s.pt或yolo11m.pt。3.2 从零跑通一次训练的命令与关键参数如果不想写脚本命令行也能一键跑yolo detect train \ datadataset/data.yaml \ modelyolo11n.pt \ epochs100 \ imgsz640 \ batch16 \ device0 \ patience20 \ projectruns/drone_car \ nameexp1把device0换成devicecpu或devicemps就切换平台。几个必须调的参数imgsz决定小目标能不能被看清无人机车辆检测里这个值往往比默认的 640 更关键batch受显存限制OOM 就往下调lr0初始学习率默认 0.01微调小数据集时可以降到 0.001 更稳。训练过程中重点看mAP50和mAP50-95两个指标前者宽松后者严格无人机小目标通常 mAP50 能到 0.7 以上就算不错mAP50-95 会低不少这是正常的。3.3 训练日志里该盯哪几个数训练一跑起来日志刷得飞快新手容易只看最后一行。实际要盯的是box_loss 和 cls_loss 是否稳定下降如果 cls_loss 震荡剧烈多半是学习率太大或类别不平衡mAP50 在验证集上的曲线如果训练集涨验证集不涨就是过拟合早停或加数据增强还有每轮的显存占用GPU 上接近上限时下一轮可能就 OOM。这些数比最终权重更能告诉你模型到底学没学到东西。4. 无人机车辆检测的避坑与排查清单4.1 小目标漏检严重先别怪模型现象训练完 mAP 看着还行但一推理远处的小车几乎全漏。原因输入尺寸太小小目标经过 backbone 下采样后特征几乎消失。解决把imgsz提到 1024 或 1280或者在数据增强里开启 mosaic 和 copy-paste增加小目标样本密度。YOLO11 本身对小目标有一定优化但输入分辨率是硬约束绕不过去。4.2 类别索引错位导致 loss 为 NaN现象训练刚起步 loss 就是 nan 或异常大。原因data.yaml里的names索引和标签 txt 里的 class 对不上或者 COCO 转 YOLO 时 category_id 没重映射。解决写个脚本统计所有 txt 里出现过的 class 值和names的 key 集合比对多一个少一个都能查出来。这个检查我每次换数据集都做五分钟省几小时。4.3 Mac 上 mps 报算子不支持现象Mac 上devicemps跑着跑着报错提示某算子未实现。原因MPS 后端对部分 PyTorch 算子支持不完整YOLO11 某些增强或损失计算会踩到。解决先升级 torch 和 ultralytics 到较新版本很多算子已经补上仍报错就退回devicecpu或者把workers0关掉多进程加载Mac 上多进程数据加载也常出问题。4.4 验证集指标虚高实际部署拉胯现象val mAP 很高换一批新图就崩。原因训练验证划分时同一场景的帧被分到了两边数据泄漏。解决按视频源或场景划分同一段视频的帧只能进一个集合。这个坑在无人机数据里特别常见因为很多数据集是从视频抽帧来的。4.5 标注框越界与零面积框现象训练时警告某些标签无效或转换后框消失。原因VOC 里 xmin 大于 xmax、框超出图像边界、宽高为 0。解决转换脚本里加裁剪和过滤宽或高归一化后小于 0.001 的框直接丢弃这类框对训练只有负作用。5. 用验证脚本确认模型真的能用以及一个提点小技巧训完不等于能用得用独立脚本在验证集甚至几张没见过的图上跑一遍看框画得对不对。下面这段推理脚本把预测结果画出来存盘肉眼过一遍比看指标更直接。from ultralytics import YOLO import cv2 model YOLO(runs/drone_car/exp1/weights/best.pt) def predict_and_save(img_path, out_path, conf0.25): results model.predict(sourceimg_path, confconf, imgsz1024, devicecpu) for r in results: # 直接在原图上绘制检测框 annotated r.plot() cv2.imwrite(out_path, annotated) # 打印每个框的类别和置信度方便核对 for box in r.boxes: cls int(box.cls[0]) print(model.names[cls], float(box.conf[0])) predict_and_save(test/drone_001.jpg, test/out_001.jpg)逻辑说明加载训练好的best.pt对单图推理r.plot()返回画好框的图存盘后人工核对。参数说明conf0.25是置信度阈值无人机小目标可以降到 0.15 看召回但误检会变多实际部署要按业务权衡imgsz推理时最好和训练时一致否则尺度不匹配精度会掉。一个提点小技巧无人机车辆检测里车辆朝向和长宽比是有先验的横着的车和竖着的车在俯视图里比例差异明显。可以在后处理阶段加一个简单的长宽比过滤把明显不符合车辆形态的框滤掉误检能降一截。这个不需要改模型纯后处理成本极低。我自己踩过最深的坑是第一次拿到无人机数据集图省事直接用默认 640 训结果小目标全丢还以为是数据集标注有问题折腾了两天才发现是分辨率的事。后来养成习惯拿到任何无人机数据先把imgsz和真实目标像素尺寸对一遍再动手训。希望帮到你。本文还有配套的精品资源点击获取
