ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

俯视航拍小目标三轮车检测数据集:5756张双格式标注与YOLO训练实战

俯视航拍小目标三轮车检测数据集:5756张双格式标注与YOLO训练实战 简介面向俯视航拍场景中的小型交通工具检测任务这份数据集包含五千七百五十六张现场图片及对应标注类别覆盖遮阳蓬三轮车与三轮车两个类别总计两万零二百七十七个标注框能直接用于小目标检测模型的训练与评测。压缩包共两千个文件以VOC格式的xml标注文件为主并附txt格式使用说明整体大小约三百三十四兆字节便于直接接入YOLO、Faster R-CNN等常见检测训练流程省去自行转换格式的额外工作。数据同时提供Pascal VOC与YOLO两种组织方式适合目标检测学习者、算法工程师以及航拍视觉方向研究者进行小目标识别训练、模型效果验证和误检漏检分析。已有二百二十八人浏览学习特别提醒此类俯视小目标样本本身训练难度较高精度指标偏低属于常见现象应更关注能否稳定检出目标这一实战能力。1. 俯视航拍小目标三轮车遮阳伞车检测数据集5756张双格式标注到底能做什么这是一份俯视场景航拍小目标三轮车遮阳伞车检测数据集5756张图片、2个类别Pascal VOC和YOLO双格式标注齐全。俯视航拍意味着绝大多数目标在画面里只有几十到一两百像素属于典型的小目标数据。拿到手第一轮训练mAP大概率不好看——低AP是这类数据集的常态重点应该是“能不能稳定检测到目标”而不是分数达标。这份资源适合做智慧交通、城市治理、保险定损或无人机巡检算法验证的从业者新手可以拿它跑通整个YOLO流程熟手可以直接用它做小目标检测头的改进实验。2. 数据内部结构VOC与YOLO标注的字段、类别分布和数据规模2.1 文件结构jpg、xml、txt三件套的含义压缩包里每一张图片配套一个同名的.xml和一个同名的.txt没有单独的mask分割路径文件。描述里专门强调“不包含分割路径的txt文件”意思是它只提供检测必须的图片和两种检测标注不涉及实例分割那套数据。文件配套关系文件类型数量内容.jpg5756航拍俯视原图RGB三通道.xml5756Pascal VOC格式标注记录类别名和绝对坐标框.txt5756YOLO格式标注归一化的中心点坐标和宽高VOC的xml文件里核心字段是filename、object、name和bndbox。bndbox里是xmin、ymin、xmax、ymax四个绝对像素值单位就是图片本身的像素坐标不需要额外换算。YOLO的txt文件则完全不同每一行对应一个目标格式是class_id x_center y_center width height其中四个坐标值全部除以图片宽高做了归一化取值在0到1之间。两份标注描述的是同一个框但一个适合人看、一个适合训练器直接读取。通常我拿到这类数据会先随机挑三张图把xml里框的坐标反算回图上画出来再检查txt里对应的坐标是否一致。这种“双格式一致性检查”能筛掉绝大多数标注错位问题。这个数据集两张标注都齐全省去了格式转换的步骤但数量校验仍然要做后面第四章会写具体命令。2.2 类别与框数分布两种三轮车怎么区分数据集的类别定义是awning-tricycle和tricycle两个。从名称和简介里的中文备注看前者是带遮阳蓬的电动车或三轮车后者是普通三轮车包含电动三轮和脚力三轮两种。类别统计如下类别名含义框数awning-tricycle遮阳蓬电动车或三轮车8260tricycle三轮车含电动三轮和脚力三轮12017合计20277两个类别的框数比例大约是1:1.45谈不上严重的类别不平衡不需要特意做重采样或者损失函数加权。真正值得警惕的是类别语义边界有遮阳蓬的三轮车一旦去掉蓬视觉上就和tricycle高度相似模型很容易学成“画面里有没有一块篷布”而不是“这是一辆什么车”。在俯视视角下遮阳蓬是圆的或方的色块和三轮车车身颜色接近时两个类别之间会频繁互相误检。这属于标注定义本身的歧义不是数据质量问题使用时要心里有数。另外要留意的是航拍小目标的框尺寸大多很小。虽然简介没有给出框的面积分布但“小目标一般很难训练”这句说明已经暗示了数据分布大量GT框在整图里占比很低缩放到640分辨率后可能只剩十几个像素。这种数据不能按常规目标检测的评估标准去死磕mAP后面第五章会展开讲。2.3 增强与真实性为什么强调“部分有增强”简介里特别指出“数据集部分有增强”并要求下载前先看图片预览确认符合要求。这种说明在航拍数据集里很常见——增强手段一般是mosaic拼图、随机旋转、亮度扰动、高斯噪声之类的组合目的是增加环境多样性。代价是小目标在增强过程中容易被裁剪掉一部分或者因为亮度变化和背景融为一体导致标注框里的目标视觉上不清晰。下载前我建议先去发布页把预览图看一遍重点看两件事一是目标的像素尺寸和你的业务场景是否匹配二是增强后的图片是否有明显模糊或遮挡。如果预览图里目标已经小到肉眼勉强辨认那训练时mAP偏低是必然的这属于数据固有属性。简介里那句“只要能检测到目标即可”其实是在定预期这类资源的价值在于提供真实俯视视角下的目标分布而不是提供一份刷高分的现成数据集。把预期定在这个位置后面训练和评估的心态会稳很多。3. 把数据集组织成YOLO训练工程目录拆分、config和超参选择3.1 目录组织按YOLO习惯重排数据解压后的原始目录大概率是jpg、xml、txt混在一起而YOLO训练工程要求images和labels分目录且train、val分文件夹。我一般会写个脚本一次性完成拆分、划分和类别名到id的映射。import os import random import shutil from xml.etree import ElementTree as ET src dataset_raw # 解压后的目录jpg/xml/txt混在一起 dst dataset_yolo classes [awning-tricycle, tricycle] name2id {name: idx for idx, name in enumerate(classes)} random.seed(42) os.makedirs(f{dst}/images/train, exist_okTrue) os.makedirs(f{dst}/images/val, exist_okTrue) os.makedirs(f{dst}/labels/train, exist_okTrue) os.makedirs(f{dst}/labels/val, exist_okTrue) jpgs [f for f in os.listdir(src) if f.lower().endswith(.jpg)] random.shuffle(jpgs) val_count int(len(jpgs) * 0.1) # 验证集占 10% for i, jpg in enumerate(jpgs): xml_path os.path.join(src, jpg.replace(.jpg, .xml)) split val if i val_count else train shutil.copy(os.path.join(src, jpg), f{dst}/images/{split}/{jpg}) txt_lines [] tree ET.parse(xml_path) for obj in tree.findall(object): name obj.findtext(name) box obj.find(bndbox) xmin float(box.findtext(xmin)) ymin float(box.findtext(ymin)) xmax float(box.findtext(xmax)) ymax float(box.findtext(ymax)) img_w float(tree.findtext(size/width)) img_h float(tree.findtext(size/height)) x_center (xmin xmax) / 2 / img_w y_center (ymin ymax) / 2 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h txt_lines.append(f{name2id[name]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) with open(f{dst}/labels/{split}/{jpg.replace(.jpg, .txt)}, w) as f: f.write(\n.join(txt_lines))这段脚本的逻辑是先从xml读取类别名和绝对坐标再从size节点拿到图片宽高把绝对坐标转成YOLO需要的归一化中心点坐标和宽高最后写进对应split的labels目录。random.seed(42)保证每次运行划分结果一致复现实验时不会因为随机划分不同而影响对比。验证集比例10%对小数据集来说够用但如果你打算做严格的小目标评估建议提高到15%到20%并且尽量保证验证集里两个类别的框数比例和全集一致。注意脚本里我把xml转txt又重新做了一遍。虽然数据集本身已经提供txt但保留这个过程有两个好处一是可以顺手校验原txt和xml是否一致二是如果之后要改类别定义或过滤某些框直接从xml这个“源格式”重新生成更可靠。实际使用时你也可以跳过转换直接用原始txt。3.2 数据集配置文件与训练启动参数YOLO系列工程ultralytics读取数据集靠一个yaml文件。这个数据集只有两个类别配置很简单。# dataset.yaml path: dataset_yolo train: images/train val: images/val nc: 2 names: 0: awning-tricycle 1: tricyclepath是数据集根目录的绝对路径或相对路径train和val以及两份images和两份labels是配套的图片在images/train对应的txt就在labels/train。nc是类别数names列表顺序必须和txt里的class_id一致——这里0对应awning-tricycle1对应tricycle和上一个脚本里name2id的映射保持了一致。训练命令我一般这么起yolo detect train \ modelyolov8s.pt \ datadataset.yaml \ imgsz1280 \ batch8 \ epochs150 \ lr00.0005 \ mosaic0.5逐项说明modelyolov8s.pt表示用COCO预训练权重做初始化而不是随机初始化从头训小目标场景下迁移学习的效果远好于从零开始imgsz1280是整份数据里最关键的一个参数默认640对航拍小目标来说是灾难性的放缩一次目标就没剩几个像素了batch8要结合显存来定24G以下的卡建议s版本配8如果显存不够就先用yolov8n并保持1280输入lr00.0005比默认值低一半小目标数据的梯度本身比较噪学习率偏保守更容易稳定mosaic0.5是把mosaic概率降到一半增强太强反而容易把小目标糊掉。如果你想用yolo11系列模型名换成yolo11n.pt或yolo11s.pt即可参数逻辑相同。跑通之后再看loss曲线和验证集的预测效果而不是只看mAP。3.3 小目标场景下的超参调整从anchor到输入分辨率小目标训练超参数里优先级最高的是imgsz其次是mosaic和lr0最后才是anchor。现在的YOLO版本都有自动anchor机制训练时默认会重新聚类计算anchor尺寸不需要手动设置。但如果你用的是旧版YOLOv5或者自己魔改的检测头就值得用k-means在训练集上重新算一遍anchor因为COCO那组anchor对俯视三轮车这种尺度偏小、且宽高比相对固定的目标并不合适。下面是我在这个数据上常用的参数范围参数建议范围调整逻辑imgsz1280~1536显存够就1536小目标提升最明显batch4~16batch太小BN容易炸太大显存不够lr00.0003~0.001出现loss震荡就往下调mosaic0.3~1.0最后10个epoch建议关闭epochs150~300看val_loss是否还在下降patience30早停阈值避免无意义等待还有一个细节如果显存不够跑到1280可以考虑把图片按比例缩放到1280的短边并用rect模式训练避免resize过度拉伸。ultralytics的rectTrue会按批次内相近宽高比分组减少无效padding但对数据loader的排序逻辑有要求新手不建议一上来就开。“小目标增强模块”这类改造比如在主干网络加P2检测头、给neck加BiFPN都是在这份数据上做改进的常规方向。但我的建议是先跑一份baseline把输入分辨率、训练参数调到合理范围确认问题出在模型容量还是数据尺度再动手改结构。直接魔改网络对新手来说很容易陷入调参深渊。4. 7z压缩包处理解压命令、完整度校验和三个常见翻车点4.1 解压7zLinux与Windows下的工具选择数据集的压缩格式是7z解压工具的选择很关键。Linux服务器上最常见的是p7zip包命令如下# Ubuntu/Debian 系安装 p7zip sudo apt install p7zip-full # 解压到指定目录-o 后面不能有空格 7z x dataset.7z -o./dataset_raw7z x和7z e的区别是解压风格不同x会保留压缩包内的目录结构自动按原路径重建文件夹e会把所有文件平铺到当前目录不保留路径。这个数据集的文件名前缀都是firc_street_平铺下来也能分辨但养成用x的习惯更安全万一压缩包里还有子目录就不会全部混在一层。Windows环境下安装7-Zip之后可以直接用命令行调用# 解压到指定目录注意 -o 参数后紧跟路径、中间没有空格 C:\Program Files\7-Zip\7z.exe x D:\download\dataset.7z -oD:\download\dataset_raw注意PowerShell里路径带空格时必须用引号包起来。如果你不想接触命令行直接用7-Zip图形界面右键选择“提取到指定文件夹”也行效果和7z x一致。服务器上没有图形界面时优先走命令行。4.2 完整度校验别解压完就开训很多人解压完看一眼文件数量就急急忙忙去训练结果跑了一半报“找不到对应的jpg”。正确的顺序是先测完整性再统计数量最后才是组织目录。# 测试压缩包完整性不实际解压输出 Everything is Ok 才安全 7z t dataset.7z # 解压后统计三类文件数量都应该等于 5756 find dataset_raw -name *.jpg | wc -l find dataset_raw -name *.xml | wc -l find dataset_raw -name *.txt | wc -l # 查看整体占用空间 du -sh dataset_raw7z t会逐个文件做CRC校验。如果输出里有Data Error或者CRC Failed说明压缩包文件损坏常见原因是下载过程中断或者存储介质有问题必须重新下载不要尝试用残缺文件训练。find和wc -l组合是Linux下最直接的计数方式三条命令分别统计jpg、xml、txt数量任何一个不是5756就说明解压不完整。如果下载到的是分卷压缩包比如dataset.7z.001和dataset.7z.002要确保所有分卷放到同一个目录后再执行7z x dataset.7z.001程序会自动读取后续分卷。缺一个分卷会直接报错而且错误信息不会提示你具体缺哪个文件需要自己对照发布页的文件列表检查。4.3 解压后需要检查的关键点解压不是结束只是开始。我一般会按下面这个清单过一遍确认数据可用再进训练流程。检查项期望值异常处理jpg文件数5756少于5756则压缩包损坏或下载不完整xml文件数5756和jpg数量不一致则标注缺失不能用txt文件数5756同上是否有空txt0个或极少出现大量0字节txt说明标注缺失使用前必读.txt存在里面可能有增强说明或额外注意事项图片尺寸统一或符合航拍特征尺寸混乱会影响imgsz设定空txt的问题容易被忽略YOLO训练时如果某张图的txt文件存在但内容是空字符串它会被当成无目标图片参与训练产生不必要的负样本。轻微一两个不影响但如果大量出现就要回去看xml里是不是本来就没有object节点。遇到这种情况我的做法是写脚本扫描并单独报告空文件先确认是数据本身的问题还是解压不完整再决定是补下载还是直接剔除空样本。还有一点容易踩坑压缩包里可能带了使用前必读.txt这类说明文件务必先打开看。有些注意事项会在里面写详细比如增强程度、部分图片的拍摄环境、标注的边界规则。这些信息在训练前看一遍能省去很多瞎猜的时间。5. 小目标训练避坑指南mAP低、BN爆炸和类别串检的排查记录5.1 mAP低得离谱先查输入分辨率而不是怀疑数据现象默认640分辨率训练完mAP0.5只有0.2到0.3置信度0.5以上的预测框少的可怜可视化出来全是漏检。原因俯视航拍图里三轮车的GT框面积占比本来就很小缩放到640后目标可能只剩十几个像素甚至比feature map上一个网格还小。mAP对目标位置和框的IoU非常敏感小目标框只要偏几个像素IoU就掉到0.5以下直接算漏检。解决先把imgsz提到1280重新训练或微调看mAP是否明显回升。如果显存不够换成yolov8n或yolo11n这种轻量主干保持1280输入。评估时也强制用同样的imgsz1280不要训练1280、验证640那等于自己砍自己一刀。这部分我见过太多人忽略默认参数跑完就下结论说数据不行实际是尺度的坑。5.2 训练中loss变成NaN或者BN参数爆炸现象训练到某个epoch后loss突然变成NaN或者逐渐飙升失控训练中断日志里能看到BN层的running_mean/running_var出现极端值。原因小目标数据本身梯度噪声大过强的mosaic和随机旋转会让目标周围混入大量高对比度背景梯度一会朝这个方向一会朝另一个方向。再加上lr0设得高、batch设得小BN统计量就容易跑飞。这是小目标训练的经典并发症不是数据集的错。解决把lr0降到0.0005以下batch提到至少8用更小的模型换空间mosaic从默认的1.0降到0.5并且设置close_mosaic10让最后10个epoch关闭mosaic来稳定BN。如果已经NaN了直接重新开始这轮训练不要尝试从NaN的checkpoint续训。5.3 awning-tricycle和tricycle互相误检遮阳蓬类别的AP明显低现象混淆矩阵里两个类别之间有大量串检单独按类别统计AP时awning-tricycle低于tricycle可视化发现漏检的全是带蓬的车。原因类别定义本身存在视觉重叠——一只手拉三轮装了遮阳蓬就属于awn-tricycle没装就是tricycle。俯视角度下遮阳蓬可能正好和车身颜色接近或者在画面边缘被裁切一半模型没有足够的判别特征。解决先按类别拆分统计AP确认是不是只有这一个类别在拖后腿。如果确认是语义混淆问题有三个选择一是把两个类别合并成“tricycle”一个类重新训练牺牲分类细度换检测稳定二是在后处理里把两个类别的输出按业务规则合并比如只要置信度超过阈值的都算三轮车三是检查是否有样本被标错——比如图片里明显没有蓬的车被打成了awning-tricycle。第三点需要人工抽检工作量不小但对这个数据集来说收益最大。5.4 7z解压报CRC错误或文件数对不上现象7z t输出Data Error in file.7z或者解压完统计jpg数量只有5748少了几个。原因下载过程中网络中断导致压缩包不完整或者是反复断点续传导致文件损坏。另一个隐蔽原因是硬盘空间不足解压到一半被系统中断但错误信息往往不直观。解决先df -h确认磁盘余量再7z t确认压缩包本身是否完整。如果校验都不过重新下载整个压缩包不要试图只用残缺文件跑数据。下载完立刻对比发布页给的压缩包大小如果大小不一致就不要解压了直接重下。这个坑和模型训练无关但会浪费你半天时间值得先排除。5.5 验证集召回高、精度低误检框密密麻麻现象验证集上Recall0.5到了0.8Precision却只有0.3预测框在图片上铺了一片把地面纹理、树影、屋顶杂物全框进去。原因俯视场景背景复杂加上小目标模型为了找回真实目标会把阈值放的很低背景区域也被当成候选目标。尤其是航拍图中深色圆形物体和三轮车轮胎高度相似模型学到的“像车”特征在背景上被大量激活。解决把conf阈值从默认0.25调到0.45以上先看误检是否明显下降如果降下来但召回也崩了说明模型本身区分能力不足。更彻底的方案是做hard negative mining把高置信度误检的区域从原图裁出来作为负样本加入训练集重新训练一轮。这个方法在航拍场景里很管用但要控制负样本数量加太多会把模型带偏成“什么都不要检”。6. 进阶验证技巧用切片推理和分尺寸mAP判断模型真实水平航拍小目标数据集的训练和评估不能只盯着那个总mAP数字。我常用的进阶验证手段是切片推理和分尺寸统计先用SAHI把原图切成512的小块分别推理再按GT框面积分桶看召回情况。切片能直观反映模型在下游业务里能不能真的找到目标分尺寸统计能告诉你漏检到底发生在哪个尺度区间。# SAHI 切片推理对验证集做预测 sahi predict \ --source dataset_yolo/images/val \ --model_path runs/train/weights/best.pt \ --model_type yolov8 \ --slice_width 512 \ --slice_height 512 \ --overlap_ratio 0.2 \ --project sahi_outputslice_width和slice_height是切片尺寸对输入图片尺度在1280到1500的图像来说512是常用值overlap_ratio是相邻切片的重叠比例0.2能有效减少目标被切断的概率。切片推理的原理是把大图拆成小块分别检测再按原坐标合并结果目标在每一块里占的比例变大了检测头更容易提取特征。代价是推理时间成倍增加一次验证大概比整图推理慢3到5倍。切片推理跑通之后再回到ultralytics的验证接口看分尺寸指标。用小目标数据集做实验时我会写脚本把GT框按面积分桶分别统计小、中、大三档的召回如果小目标档的recall明显低于其他档说明改输入分辨率和切片还救不回来下一步才考虑改网络结构加小目标检测头。我在claude里会这样验证跑一遍model.val()之后提取per-class AP和AR数值优先对比两个类别的AP差距再去判断是数据标注的类别语义问题还是模型能力问题。顺序颠倒很容易被总mAP误导把精力浪费在不该改的地方。从那以后我每次拿到俯视航拍小目标数据集都会强制走一遍“先统计框尺寸分布再调imgsz跑baseline最后用切片推理验证召回”这个流程确认问题出在数据尺度还是模型结构才决定要不要动网络。希望这个习惯也能帮到你。本文还有配套的精品资源点击获取
返回列表