
简介这是一份面向目标检测方向的无人机识别数据集适合深度学习初学者和算法工程师用于模型训练与算法验证。数据集包含9229张无人机图片并同时提供YOLO与VOC两种格式的标注信息既能直接用于YOLOv5至YOLOv10等主流系列训练也能用于Faster Rcnn、SSD等常见检测框架。资源包共2000个文件以txt标注文件为主体另含1个yaml类别配置文件及xml标签整体压缩包大小为814.16MByaml文件指定了类别信息xml标签则便于按VOC格式读取兼容性较强。数据集已按训练集、验证集和测试集划分完毕用户下载后无需额外整理直接接入训练脚本即可运行能够显著节省数据准备时间。目前已有339人学习该资源对于希望快速获得无人机检测数据、减少数据预处理工作量的研究者而言是一个实用选择。1. 无人机识别数据集为什么不能直接套用通用目标检测数据集把无人机当作检测目标第一反应往往是拿 COCO、VOC 里现成的aeroplane类别来训。但真正落到航拍反制、低空安防、机场净空监测这类场景时会发现通用数据集里飞机类别大多是民航客机或小型固定翼机身大、背景单一、拍摄角度以水平或俯视为主而需要识别的消费级无人机尺寸往往只有几十像素旋翼特征不明显还会混入飞鸟、风筝、气球这些外观相似物。换一句话说无人机识别数据集解决的不是认不认得飞机的问题而是如何在复杂背景下把厘米级目标从噪声里挑出来的问题。这篇内容围绕数据集本身展开公开数据集怎么选、标注格式怎么转换、用 YOLO 系列怎么训练以及自建数据集时哪些环节最容易被低估。2. 无人机识别数据集的构成与选择标准2.1 公开数据集的场景覆盖与规模差异无人机检测方向公开数据集不少但各有侧重。常见的有 Det-Fly、UAVDT、UAV123、Drone-vs-Bird 等。这里先明确一点这些数据集不是互相替代的关系而是对应不同的检测假设。数据集目标类型视角难点标签典型规模Det-Fly无人机 / 飞鸟仰视、平视尺度小背景为天空或建筑上万个标注框UAVDT车辆 / 行人为主俯视无人机平台拍摄目标密集约 4 万帧UAV123单目标跟踪俯视跟踪任务也可做检测123 个序列Drone-vs-Bird无人机 vs 飞鸟仰视类别混淆运动模糊几十个视频序列上面表格里Drone-vs-Bird 这类数据集对安防场景尤其有价值。它专门把无人机和鸟类放在一起逼着模型去学旋翼带来的纹理差异和飞行轨迹特征。UAVDT 则比较适合做平台视角的检测因为它的拍摄视角来自无人机本身目标从高空往下看时形态和地面监控完全不一样。选择数据集的判断标准通常有三个目标尺度分布、背景多样性、负样本比例。如果要做低空反制优先选仰视视角、天空背景占主体的数据集如果做无人机巡检或航拍监控则选俯视视角的数据集。2.2 标注格式直接决定训练管线的复杂度拿到数据集之后第一个要确认的就是标注格式。目前目标检测数据集最常见的是三种COCO 的 JSON 格式、Pascal VOC 的 XML 格式、YOLO 的 TXT 格式。三者之间的转换是训练前的固定动作。COCO 格式的标注结构大致是 images 数组加 annotations 数组每个 annotation 里有 image_id、category_id、bbox、area、iscrowd 等字段。其中 bbox 是[x, y, width, height]注意是左上角坐标加宽高单位是像素。VOC 的 XML 则把每个目标放在object节点下通过bndbox记录xmin, ymin, xmax, ymax。YOLO 格式则完全不同它保存为每张图片对应的 txt 文件一行一个目标格式为class_id x_center y_center width height且全部归一化到 0-1。实际处理数据集时多数开源数据集直接提供 COCO 或 VOC 标注需要转换成 YOLO 格式才能丢进 YOLOv5 或 YOLOv8 训练。那个转换脚本并不复杂但有几个细节容易出错后面单独展开。如果数据集已经给了 YOLO 格式的 txt 和 images 目录反而要先检查归一化坐标有没有越界、类别 id 是否连续这两类问题非常常见。2.3 数据质量评估先看标注一致性再看数量数据集规模大不等于可直接使用。无人机识别数据集常见质量问题是漏标和框不准。例如一串连续视频帧里无人机偶尔被枝叶遮挡标注人员可能直接跳过这几帧这就给训练引入了错误负样本。另一个问题是框的紧致程度不一致有的标到旋翼边缘有的只包住机身会导致模型回归分支无所适从。评估质量时有一个成本很低的办法把标注框画出来按视频帧序列抽查 100 张图统计三类错误——漏标目标的比例、框偏移超过目标尺寸 30% 的比例、类别错误的比例。这三项里漏标的影响最大因为它会把目标区域当成背景模型在推理时倾向于把真实无人机也判成背景。3. 用 YOLOv8 在自己选定的无人机数据集上跑通训练全流程3.1 数据目录结构与训练集划分拿到数据集后建议把数据整理成 YOLO 标准目录结构这是最稳妥的做法。这里以 Det-Fly 数据集为例演示实际上换其他数据集也通用。datasets/ └── drone_det/ ├── images/ │ ├── train/ # 训练图片 │ └── val/ # 验证图片 └── labels/ ├── train/ # 每张图片对应的 txt 标注 └── val/划分比例一般按 8:1:1 或者 9:1 处理测试集可以单独留出一部分完全不参与训练和验证。无人机视频数据集有一个隐含问题相邻帧之间高度相关如果随机划分训练集和验证集同一段视频的相邻帧可能同时出现在两边导致验证指标虚高。正确做法是按视频序列划分而不是按帧划分保证同一个视频只出现在一个集合里。3.2 从 COCO JSON 转 YOLO 标注的实用脚本这里给出一个可以直接改编的 Python 脚本用于把 COCO 格式标注转成 YOLO txt 格式。脚本支持按图片 id 过滤以便只转换训练集或验证集部分。import json import os def coco_to_yolo(coco_json_path, output_dir, images_info): with open(coco_json_path, r, encodingutf-8) as f: coco json.load(f) # 建立 image_id 到文件名的映射 img_id_to_name {} for img in coco[images]: img_id_to_name[img[id]] img[file_name] # 按图片组织标注 anns_by_img {} for ann in coco[annotations]: img_id ann[image_id] if img_id not in anns_by_img: anns_by_img[img_id] [] anns_by_img[img_id].append(ann) os.makedirs(output_dir, exist_okTrue) for img_id, file_name in img_id_to_name.items(): if file_name not in images_info: continue # 获取该图片的宽高用于归一化 img_w images_info[file_name][width] img_h images_info[file_name][height] txt_path os.path.join( output_dir, os.path.splitext(file_name)[0] .txt ) with open(txt_path, w) as f: for ann in anns_by_img.get(img_id, []): # COCO bbox 格式: [x, y, width, height] x, y, w, h ann[bbox] # 转换为 YOLO 格式: x_center, y_center, width, height x_center (x w / 2) / img_w y_center (y h / 2) / img_h w_norm w / img_w h_norm h / img_h # 防止归一化坐标越界裁剪到 [0, 1] x_center max(0, min(1, x_center)) y_center max(0, min(1, y_center)) w_norm max(0, min(1, w_norm)) h_norm max(0, min(1, h_norm)) cat_id ann[category_id] # 如果类别 id 不连续需要做映射 f.write(f{cat_id} {x_center:.6f} {y_center:.6f} {w_norm:.6f} {h_norm:.6f}\n)脚本逻辑说明核心是拿到每张图片的宽高把 COCO 的左上角坐标加宽高换算成中心点坐标加宽高再除以图片尺寸完成归一化。images_info参数是一个字典键是文件名值是包含宽高的字典实际使用时可以来自 COCO 的images字段。需要手动调整的地方有两个类别 id 映射到 0 开始的连续整数以及iscrowd为 1 的标注是否跳过这取决于具体任务。3.3 准备 YOLOv8 数据配置并启动训练标注转换完成后还需要一个 YAML 文件告诉 YOLOv8 数据在哪里、类别有哪些。以单类别无人机检测为例内容如下# drone.yaml path: datasets/drone_det train: images/train val: images/val names: 0: drone启动训练命令如下yolo detect train \ modelyolov8n.pt \ datadrone.yaml \ epochs100 \ imgsz640 \ batch16 \ device0 \ projectruns/drone \ nameexp1参数说明model指定预训练权重yolov8n.pt是 nano 版本参数量最小适合先验证流程imgsz是输入尺寸无人机目标小可以尝试 960 或 1280但显存占用会上升batch按显存调整16 对应 12GB 显存左右8GB 显存建议降到 8device0指定第一块 GPU。训练完成后验证集上的 mAP50 和 mAP50-95 会打印在终端里。3.4 训练参数里值得优先调整的三个值第一个是imgsz。无人机识别数据集里大量目标边长不超过 20 像素640 输入下这些目标映射到特征图上只剩一到两个像素点特征提取非常困难。把输入尺寸提高一倍小目标的像素面积会翻四倍检测效果提升往往非常明显。代价是训练和推理速度下降。第二个是mosaic增强。YOLOv8 默认在训练前 10 个 epoch 开启 mosaic把四张图拼在一起对小目标有益但如果背景过于复杂模型可能学到背景纹理而不是目标本身可考虑把mosaic关闭。第三个是close_mosaic和cache的组合小数据集上开启cacheTrue可以显著减少磁盘 IO 等待。4. 无人机识别数据集常见训练陷阱与调优策略4.1 小目标漏检与推理时滑窗检测无人机识别数据集训练完模型后最典型的失败模式是小目标漏检。模型在 640 输入下能正常检测训练集里的目标一到实际使用就失效往往不是模型问题而是推理模式和训练模式不匹配。YOLOv8 默认会把输入图像缩放到imgsz如果原始图像很大比如 4K 分辨率的航拍图缩放后无人机可能缩小到几个像素检测不到。常见的做法是滑窗推理。把大图切成若干 640×640 或 960×960 的窗口每个窗口独立送进模型再把结果映射回原图坐标。窗口之间设置 10% 到 20% 的重叠防止目标正好落在窗口边缘被切开一分为二。重叠部分的重复检测框用 NMS 合并。滑窗推理的缺点是耗时成倍增加实际使用中可以通过步长控制速度和召回率的平衡。def sliding_window_detect(model, image, window_size640, stride512): h, w image.shape[:2] detections [] for y in range(0, h, stride): for x in range(0, w, stride): # 限制窗口不超出图像边界 win image[y:y window_size, x:x window_size] results model.predict(win, imgszwindow_size, verboseFalse) for box in results[0].boxes: x1, y1, x2, y2 box.xyxy[0].tolist() conf box.conf[0].item() # 坐标还原到原图 detections.append((x x1, y y1, x x2, y y2, conf)) return detections这段代码把原图按stride步长切成窗口每个窗口独立推理。坐标还原时把窗口左上角的偏移量加到检测框坐标上即可。stride小于window_size时窗口有重叠配合后续 NMS 可以处理目标跨窗口的问题。4.2 负样本与难例挖掘对精度的实际影响无人机识别数据集的负样本问题往往比正样本更棘手。背景里的飞鸟、风筝、气球、远处的信号塔、云层边缘都可能被模型误判为无人机。单纯增加负样本图片数量并不一定能解决问题因为这些背景元素跟无人机正样本在纹理上差异较大模型很容易区分。真正难的是那些局部特征和无人机相似的负样本。处理难例的常见做法是难例挖掘。把训练好的模型放到真实测试图片上做推理挑出置信度在 0.3 到 0.7 之间的假阳性框把这些区域的图像裁剪出来作为负样本加入训练集。这个操作看起来简单但需要控制加入比例一般不超过一个 batch 的 20%否则会让模型过于保守召回率反而下降。另一种低成本方法是把真实无人机图片通过随机旋转、灰度化、加噪处理后贴到纯色背景上作为简单正样本补充。这种做法能很快扩大样本量但只对过拟合严重的小数据集有效对真实场景增益有限需谨慎使用。4.3 置信度阈值与 NMS 参数在无人机场景下的调整无人机目标小且有时密集默认的置信度阈值和 NMS 参数不一定合适。YOLOv8 推理时默认conf0.25、iou0.45。在无人机识别场景中如果追求召回率把conf降到 0.1 或 0.05可以找回不少小目标。但代价是假阳性明显增多。NMS 的iou阈值决定了两个高度重叠的框是否合并。无人机目标小框与框之间的 IoU 通常不会特别高但如果一架无人机的两个旋翼之间被检测出两个框适当降低 iou 到 0.3可以避免误删。需要注意的是NMS 会把置信度低的框删掉所以调低conf的同时不要调低iou太多不然同一个目标会被多个框包围。实际调参的顺序建议是固定 iou 先调 conf找到合理漏检率后再微调 iou。5. 数据增强让无人机识别数据集发挥更大价值5.1 针对无人机的增强组合YOLOv8 自带一系列增强参数默认配置对通用目标检测比较友好但无人机目标有自己的特点需要针对性调整。下面是一组建议配置# augment.yaml train: hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.4 translate: 0.1 scale: 0.5 fliplr: 0.5 mosaic: 0.8 mixup: 0.1在yolo detect train时通过cfgaugment.yaml传入参数。scale控制在 0.5可以让目标在训练时随机缩小迫使模型适应更小的目标。mosaic设为 0.8保留一部分不启用 mosaic 的样本避免模型过度依赖拼接图的边缘特征。mixup开启并设小值有助于提升泛化。颜色增强参数不宜过大无人机在天空背景下颜色比较单一过度色偏会让模型学偏。5.2 用脚本做线下增强批量生成训练样本有些情况不适合依赖训练时的在线增强例如模型比较老、不支持某些增强算子或者希望把增强后的数据直接导出进行人工检查。这时可以用脚本做线下增强。一个常见方法是复制原始图片随机贴入无人机目标并同时修改标注。import cv2 import numpy as np import random def paste_drone(bg_img, drone_img, bbox_list): h, w bg_img.shape[:2] dh, dw drone_img.shape[:2] scale random.uniform(0.3, 0.8) new_dw, new_dh int(dw * scale), int(dh * scale) drone_resized cv2.resize(drone_img, (new_dw, new_dh)) x random.randint(0, w - new_dw) y random.randint(0, h - new_dh) # 随机翻转旋翼方向 if random.random() 0.5: drone_resized cv2.flip(drone_resized, 1) roi bg_img[y:y new_dh, x:x new_dw] # 简单 alpha 融合不考虑遮挡 bg_img[y:y new_dh, x:x new_dw] cv2.addWeighted(roi, 0.3, drone_resized, 0.7, 0) bbox_list.append({ x: x, y: y, w: new_dw, h: new_dh, class: 0 }) return bbox_list增强脚本的逻辑是读入背景图在随机位置粘贴缩放的无人机图同时记录新的标注框。实际工程中需要注意两点粘贴位置不能超出背景图边界粘贴时目标周围最好保留少量边缘上下文不要贴得太生硬。生成的新样本要人工抽查重点看标注框是否紧贴目标边缘。5.3 增强后效果验证的两个关键指标做完增强后的第一件事不是直接看 mAP而是检查增强前后数据分布的变化。写一个小脚本统计所有标注框的宽高分布画直方图对比增强前后小目标所占比例。如果增强后目标尺寸的分布基本符合预期再启动训练。训练完成后对比增强前后的模型时不要只看 mAP50 单一指标。无人机识别更关注小目标类别下的 AP_smallYOLOv8 训练日志里会按 COCO 的尺度定义输出不同尺寸目标的 AP。如果 AP_small 没有提升说明增强引入的样本没有命中真正的短板需要重新调整增强策略。另一个指标是误检率在固定视频片段上统计模型输出的假阳性框数量增强前后对比确认误检率没有因增强而恶化。本文还有配套的精品资源点击获取