☰
无人机视角飞机目标检测数据集:YOLOv8训练与切片推理实战
2026/10/7 5:44:54 网站建设 项目流程

简介:这是一份面向无人机高空视角的飞机目标检测数据集,专为航空器识别与追踪、机场空域监测、无人机交通管理及低空预警系统开发提供训练基础,适合目标检测算法研究者、视觉开发者和相关专业学生使用。数据全部采集自高空及无人机视角,共526张图像,配套526个YOLO格式txt标注文件,另含1个yaml配置和1个docx说明文档,总计1054个文件,压缩包仅15.63MB,即下即用。数据按训练集479张、验证集31张、测试集16张划分,单张图片最多标注20余个飞机实例,覆盖云层、城市、旷野等复杂背景,以及多种角度、高度和光照条件,可有效支撑小目标检测、密集目标识别等算法的性能验证。截至目前已有202人学习查阅,借助清晰直接的YOLO标注格式,读者可快速接入YOLOv5/v7/v8等主流框架,完成模型训练与部署。

1. 无人机视角下的飞机目标检测:这份zip里装的不只是526张图

高空视角下的飞机检测,和普通路面上检测车辆完全是两种难度。你按YOLOv5/v7/v8的标准流程跑一套Coco预训练权重,丢到无人机画面上大概率会发现:识别精度低、漏检严重,原因就是飞机在整张图里往往只占几十个像素,属于典型的小目标检测场景。这份“无人机视角飞机目标检测数据集.zip”正好补上这一环:它包含训练集479张、验证集31张、测试集16张,所有图像都采集自无人机和各类高空视角,标注统一为YOLO格式,类别只有一个plane,单张图最多标注了20多架飞机实例。它适合正在做机场空域监测、低空预警、航拍影像分析,或者单纯想把小目标检测算法在真实数据上验证一遍的工程师。拿到手不是解压就能开训,目录结构、标签路径和参数设置都有讲究,下文按我自己的实操顺序来讲。

2. 看懂Roboflow导出的YOLO格式:五个数字背后的坐标逻辑

2.1 Roboflow导出文件的命名规律

打开压缩包,你会看到大量类似P0162_png_jpg.rf.72229a80e41158b85832bb9f25503357.jpg的文件。命名里那串.rf.后面跟一长串十六进制哈希,是Roboflow平台导出时给每张原图分配的唯一ID。文件名按原图名_原格式.rf.哈希.jpg这样组合,同名的.txt文件就是这张图对应的YOLO标注。这个结构看起来有点丑,但它保证了图片和标签一一对应。我一般习惯先执行一句ls | wc -l数一下文件总数,再对比jpg和txt数量是否一致,缺一个都会让后面的训练静默出问题。

压缩包里其实已经按数据集切分逻辑分好了目录。Roboflow在导出时把全部样本随机分配成三份:479张训练、31张验证、16张测试。对工程验证来说,这个规模能让模型在1到2小时内跑完一轮完整的训练和评估;但如果要做严谨的学术评测,16张测试集确实偏少,建议你自行追加一段独立拍摄数据再下结论。

2.2 txt里的五个数字:类别、中心坐标、宽高

随便打开一个txt文件,内容大概是这样的:

0 0.482017 0.317460 0.033821 0.045401 0 0.712044 0.584973 0.028114 0.039672

每一行是一个目标实例,五个数字分别表示:类别ID、归一化后的边界框中心x坐标、中心y坐标、归一化后的框宽、归一化后的框高。因为整个数据集只有一个类别plane,所以第一个数字永远是0。这里的“归一化”是指把实际像素坐标除以图片宽高,得到0到1之间的小数。好处是无论原图是1920×1080还是4K分辨率,标注都不受缩放影响。

想把这个坐标画回原图调试时,需要反算像素坐标:

import cv2 img = cv2.imread("P0162_png_jpg.rf.72229a80e41158b85832bb9f25503357.jpg") h, w = img.shape[:2] with open("P0162_png_jpg.rf.72229a80e41158b85832bb9f25503357.txt") as f: for line in f: cls, cx, cy, bw, bh = line.strip().split() cx, cy, bw, bh = float(cx), float(cy), float(bw), float(bh) x1 = int((cx - bw / 2) * w) y1 = int((cy - bh / 2) * h) x2 = int((cx + bw / 2) * w) y2 = int((cy + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite("visualized.jpg", img)

这段代码的核心是先把归一化的中心坐标乘回宽高,再用框宽高的一半算出左上角和右下角。我建议你在训练前至少挑几张画出来看看,确认标注的不是背景、不是云的边缘,再往下走。这种可视化检查虽然笨,但对新数据集来说比看任何指标都直接。

2.3 单类别数据集:限制在哪,优势在哪

只有plane一个类别,意味着模型不需要区分民航、战斗机、无人机这些子类,它只负责把所有“像飞机”的目标从背景里框出来。训练难度比多类别检测低一截,收敛快,误检率也容易压住。加上数据里背景差异大,有云层、城市、旷野,模型学到的是飞机在不同环境下都稳定的外形特征,这对检测任务来说足够用了。

但你要明确边界:这份数据不能用来做机型识别。如果项目要求区分“这是波音还是空客”,你需要在它的基础上额外采集带型号标签的数据,再做成细粒度分类模型,而不是指望这个单类别权重帮你把型号也分出来。

3. 从zip到yolov8训练自己的数据集:目录整理、校验脚本与启动训练

3.1 解压之后先处理目录结构

Roboflow导出的常见结构有两种:一种是每个子集目录里同时混放jpg和txt,另一种是已经分好images和labels两个子目录。这份数据集以前者为主,直接把压缩包解开会看到train、valid、test三个文件夹,里面所有图片和标签文件平铺在一起。而YOLOv8约定的格式是图片放在images目录,标签放在与images同级的labels目录,然后训练时通过路径配置自动找标签。

这一步如果没做对,最典型的现象就是训练正常启动、loss也在下降,但验证集的mAP一直是0。因为模型从头到尾就没读到标签,它只会随机预测。先把目录结构统一好:

mkdir -p dataset/{train,valid,test}/{images,labels} for split in train valid test; do mv "$split"/*.jpg "$split/images/" mv "$split"/*.txt "$split/labels/" done

这段脚本把每个子集里的jpg和txt分别移动到对应的images和labels子目录。执行完后,检查一下train目录下是不是出现了images和labels两个平级文件夹,确认无误再进行下一步。之后再配合下面的data.yaml,YOLOv8就能正确识别图片和标签的位置了。

data.yaml是数据集的核心配置文件,内容如下:

path: /绝对路径/无人机视角飞机目标检测数据集/dataset train: train/images val: valid/images test: test/images names: 0: plane

path指向数据集根目录,train和val填的是相对路径,YOLOv8会自动把路径拼接成 root/train/images 去找图片,然后自动去 root/train/labels 找对应txt。names里的0对应plane,就是标注文件里那个类别ID。这里有个小细节:val配的是valid/images而不是valid/labels,因为YOLOv8只要求你给它图片路径,标签路径由它自己推理。

3.2 用Python脚本给标注做一次“体检”

目录整理好后,不要急着装环境。先写一段脚本扫描所有标签文件,把配对缺失、空文件、坐标越界这三种问题一次筛出来:

from pathlib import Path base = Path("dataset") for split in ["train", "valid", "test"]: img_dir = base / split / "images" lbl_dir = base / split / "labels" for img in sorted(img_dir.glob("*.jpg")): txt = lbl_dir / (img.stem + ".txt") if not txt.exists(): print(f"[缺失标签] {txt}") continue lines = [line.strip() for line in txt.read_text(encoding="utf-8").splitlines() if line.strip()] if not lines: print(f"[空标签] {txt}") continue for line in lines: parts = line.split() if len(parts) != 5: print(f"[格式错误] {txt}: {line}") continue cls, cx, cy, bw, bh = parts[0], float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) if not (0 < cx < 1 and 0 < cy < 1 and 0 < bw <= 1 and 0 < bh <= 1): print(f"[坐标越界] {txt}: {line}")

标注格式的五个数字必须满足条件:中心点cx和cy在0到1之间,宽高bw、bh大于0且不超过1。任何一个数字超出这个范围,都说明数据在被处理时出了问题,用YOLO训练大概率会出现loss异常或预测框飞出图像边界。跑完这个脚本如果没有输出,就说明标签整体是健康的,可以进入训练环节。

3.3 安装Ultralytics并启动第一次训练

目录和校验都没问题之后,安装Ultralytics包,然后用最小的模型先验证流程是否通:

pip install ultralytics yolo detect train data=plane.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16

这里从yolov8n.pt这个最小模型开始,是谨慎做法。它参数最少,训练速度快,先拿它确认数据和训练链路没有问题。如果一开始就用yolov8l或者yolov8x,显存和训练时间都会翻几倍,万一后面发现数据有坑,等于白白浪费时间。imgsz=640是YOLOv8的默认输入分辨率,batch=16在消费级显卡上基本都能跑动,显存只有6G的话把batch降到8即可。第一次训练的目标不是拿到多高的精度,而是看到loss曲线在下降、验证集指标不是0,这就说明流程已经通了。

4. 高空小目标检测的训练调参:imgsz、anchor与数据增强怎么定

4.1 为什么640分辨率对小目标不友好

YOLOv8在推理时会把输入图缩放到固定尺寸,比如640×640。一张1920×1080的航拍图缩小到640后,原本只有30像素宽的飞机,在输入图上可能只剩下10个像素。这个尺寸经过了模型多层卷积下采样后,特征图分辨率更小,小目标的特征几乎被抹平,模型自然就看不见了。

所以这个数据集最核心的调参点不是学习率,而是输入分辨率。你可以把imgsz提高到1280甚至1536,让模型在输入阶段就保有更多小目标细节。代价是显存占用量暴增,训练和推理速度都会明显变慢。对2560×1440这类原图,我一般先用imgsz=1280跑一轮,看val上的小目标召回率有没有明显变化,再决定要不要往上加。

这里有个取舍要放在心里:imgsz不是越大越好。分辨率提高后,原本的小物体会变大,但同时整张图里能放进的特征区域变小,模型对大目标的位置精度反而可能下降。对这份纯飞机数据集来说,飞机普遍偏小,imgsz=1280基本是收益最明显的一档。

4.2 推荐参数配置与anchor策略

把训练配置拆开看,我常用的这套组合可以直接抄:

参数推荐值说明
modelyolov8s.pt比n精度高,比m训练量小
imgsz1280提升小目标召回的关键
batch8显存不够就降到4
epochs200数据量小,200轮足够收敛
lr00.01Ultralytics默认值,不用动
patience50连续50轮无提升就提前停止

对应命令:

yolo detect train data=plane.yaml model=yolov8s.pt epochs=200 imgsz=1280 batch=8

anchor方面,YOLOv8默认的anchor是从Coco数据里聚类出来的,和无人机视角的目标尺寸分布差异较大。你不需要手动改anchor,Ultralytics在训练启动时会自动计算数据集的anchor尺寸,并打印一行提示。如果不放心,可以单独跑一次:

yolo detect train data=plane.yaml model=yolov8s.pt imgsz=1280 epochs=0

epochs=0只做校验,不实际训练,模型会重新适配当前数据集的anchor。这一步会让后续训练的小目标检出更稳定,也能提前暴露数据里的极端比例问题。

4.3 数据增强:mosaic用还是不用

Ultralytics默认开启多种数据增强,其中mosaic是最影响小目标训练的一个。mosaic会把四张图拼成一张,让同一张输入里出现更多目标,对模型泛化有帮助。但对高空小目标来说,四张图拼接后,每个目标的像素占比只会变得更小,反而加剧了小目标难检出的问题。

我的习惯是前150轮开mosaic,让模型在多样本背景下先学出稳定的特征表示;最后20到30轮把mosaic关掉,用干净的原图做微调,防止模型在拼接图的噪声上过拟合。关闭方式是在训练命令里加上mosaic=0.0。比如:

yolo detect train data=plane.yaml model=yolov8s.pt epochs=200 imgsz=1280 batch=8 mosaic=0.2

这个参数指的是mosaic概率。设成0.2表示只有20%的样本走mosaic增强,其余80%保持原图。对这份数据集我建议mosaic不要超过0.3,不然你会看到训练loss掉得很漂亮,但验证集里的小目标召回没有明显改善。另一个值得开的增强是paste_in,它会把小目标随机粘贴到其他图上,正好模拟无人机画面中目标分散的形态,对低空监测场景很对症。

5. 踩坑复盘:我用这个数据集时遇到的四个常见问题

5.1 训练正常但mAP恒等于0

现象:训练日志里loss在逐步下降,每个epoch也都正常输出precision和recall,但mAP@0.5一直显示0,或者从头到尾只有0.001这种数字。

原因:数据路径配置错误。最常见的是data.yaml里train和val写成了同一个子集路径,或者labels目录没有跟images目录并列。YOLOv8找不到标签时会直接跳过该样本,loss来自背景分类,模型实际上什么都没学到。

解决:退回第3.1节的目录整理,确认根目录下存在train/images、train/labels两两对应的目录。然后在data.yaml里把path改成绝对路径,不要用相对路径。最后跑一遍第3.2节的校验脚本,确认每个jpg都能找到同名txt。

5.2 批量resize图片后,标注框全部错位

现象:为了节省显存,把数据集里所有jpg统一resize到640×640,然后直接开训,结果可视化时发现预测框和飞机位置对不上,有的框偏左上角,有的框直接缩小到只包住半个机翼。

原因:YOLO标注里的坐标是归一化到原图宽高的,你单独resize图片却不重算标注,框的像素坐标没有同步更新,模型学到的位置自然全是错的。

解决:不要手动resize图片。要么保持原图训练,在训练命令里用imgsz控制输入尺寸;要么把图片和标注一起做变换。最简单的做法是用Ultralytics的dataset工具,或者写脚本在resize的同时按原图宽高比例更新每个txt里的cx、cy、w、h。这个坑特别隐蔽,因为resize后的图片看起来大小统一,没有明显报错,只有画框才能发现。

5.3 标签文件读取失败,报错说line is empty

现象:训练刚开始几十步就报错,提示某个txt文件内容为空,或者text file中出现了无法解析的字符,训练直接中断。

原因:Roboflow导出的txt偶尔会有UTF-8 BOM头,也有极少数空标注文件被保留了下来。另一个来源是Windows环境下用记事本编辑过txt,换行符变成\r\n,某些解析器在strict模式下会报错。

解决:用Python统一清洗一遍所有txt最省事,读取时去掉BOM和换行符,遇到空文件直接删除:

from pathlib import Path for txt in Path("dataset").rglob("*.txt"): data = txt.read_bytes().strip() if not data: txt.unlink() print(f"deleted empty: {txt}")

清洗后再备份一份原始数据。这个操作会把空文件和隐藏字符一次清掉,之后训练就不会再在这个环节翻车。

5.4 测试时把高亮云层或建筑边缘误检成飞机

现象:训练期间val loss正常,mAP也不差,但把模型接到无人机实拍视频上时,云层的高光区域、城市玻璃幕墙的反光经常被框成plane。

原因:数据量少导致的背景过拟合。虽然数据集包含了云层/城市/旷野等背景,但每种背景的样本数量有限,模型会把某些高频纹理特征和飞机混淆。加上高空视角的飞机本身外形轮廓不清晰,更容易误判。

解决:第一优先级是增加数据,在训练集中混入不包含飞机的高空负样本图,让模型学会区分“没有飞机”这个类别。第二优先级是调整置信度阈值,推理时把conf从默认0.25提高到0.4或0.5,过滤掉低置信度误检。第三优先级是用第6章会讲到的切片推理,把大图切成小块逐一检测,减少背景纹理对小目标的干扰。

6. 进阶用法:用切片推理把漏检率再压一压

模型训练完后,别急着直接对整张原图推理。高空图像分辨率高、目标小,直接整图推理时YOLO会对图像做缩放,小飞机过一遍下采样就丢了特征。切片推理的思路是:把原图切成若干有重叠的小块,每块放大后单独检测,再把所有检测结果拼回原图坐标。对小目标检测来说,这是比单纯调imgsz更直观、效果也更稳的方法。

推荐工具是SAHI,它专门配合Ultralytics模型做切片目标检测。安装和调用都不复杂:

pip install sahi sahi predict \ --source test.jpg \ --model_type yolov8 \ --model_path best.pt \ --conf 0.3 \ --slice_height 512 \ --slice_width 512 \ --overlap_ratio 0.2 \ --postprocess_type NMM \ --postprocess_match_metric IOS \ --postprocess_class_agnostic True

参数含义按顺序说:slice_height和slice_width决定每块切片尺寸,512对1280分辨率下训练的模型比较合适;overlap_ratio设0.2,让相邻切片有20%重叠,避免目标正好被切在分界线中央;postprocess_type选NMM,也就是非极大值抑制的变体,用于合并不同切片里重复检出的同一个目标;IOS匹配指标适合应对重叠框。这个组合是我跑高空数据集时反复试出来的,漏检率通常能比整图推理降低一到两成。

验证阶段也有个习惯建议保留:训练完的best.pt先跑一遍val并导出混淆矩阵,不要只盯着mAP看。小目标数据集很容易出现mAP不错、但具体到远距离小飞机全部漏检的情况,混淆矩阵能告诉你漏检到底从哪一类目标里来的。命令如下:

yolo detect val data=plane.yaml model=best.pt imgsz=1280 plot=True

跑完在runs/val目录下看confusion_matrix.png,如果plane那一行的true positive明显低于其他列,说明模型对这类样本识别不足,需要回到第4章提升分辨率或调整增强策略。

从那以后我每次拿到新的无人机或高空视角数据集,都会强制先跑一遍标注校验脚本,再按切片推理的思路做一轮验证,确认不是靠运气训练出来的模型之后,才敢把它放进监测系统里上线测试。这份“无人机视角飞机目标检测数据集.zip”虽然体量不大,但作为小目标检测的练手和验证底料很合适,希望帮到你。

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

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

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

立即咨询