别再到处找了!9个遥感目标检测数据集(UCAS-AOD/DOTA/FAIR1M等)的下载、标注格式与实战加载指南 遥感目标检测实战9大核心数据集的工程化应用指南当我在实验室第一次尝试复现遥感目标检测论文时花了整整两周时间才搞明白如何正确加载DOTA数据集——那些旋转框的标注格式让我吃尽了苦头。本文将从工程实战角度剖析主流遥感数据集的隐藏陷阱与高效加载技巧让你避开我踩过的那些坑。1. 数据集选择与获取策略1.1 按任务需求匹配数据集特性选择数据集就像挑选显微镜——分辨率、视野和样本类型必须匹配你的观察目标。下表对比了主流数据集的核心参数数据集图像尺寸范围实例数量标注类型特色类别最佳应用场景DOTA800×800~4000×4000188,282OBB立交路口/直升机复杂场景多角度目标检测FAIR1M1000×1000~10000×100001MOBB飞机型号细分(11种)军事/交通细粒度识别xView2000×2000~4000×40001MHBB工程车辆(20子类)灾害评估/基建监测UCAS-AOD1280×659~1372×94114,596HBB飞机/汽车背景负样本二分类器性能验证实战建议当你的GPU显存小于12GB时慎选FAIR1M的10000×10000图像建议预先切割为1024×1024的patch1.2 高效下载与预处理流水线原始数据集往往存在压缩包分散、下载限速等问题。这里分享我的自动化处理方案# 使用aria2多线程下载以DOTA为例 aria2c -x16 -s16 https://example.com/DOTA.zip -o ./data/ # 解压后自动校验文件完整性 find ./data -name *.zip -exec unzip -q {} \; md5sum -c checksums.txt常见预处理操作包括坐标归一化将绝对坐标转换为[0,1]相对坐标图像标准化处理不同传感器的色差问题负样本过滤清除标注文件中空白的txt文件2. 标注格式深度解析2.1 旋转框(OBB)与水平框(HBB)的转换秘籍DOTA的OBB标注看似复杂其实可以用OpenCV的minAreaRect轻松处理import cv2 import numpy as np # DOTA格式(x1,y1,x2,y2,x3,y3,x4,y4) points np.array([[x1,y1],[x2,y2],[x3,y3],[x4,y4]], dtypenp.float32) rect cv2.minAreaRect(points) # 得到旋转矩形(center, (w,h), angle) # 转换为MMDetection需要的格式 angle rect[2] if rect[1][0] rect[1][1] else rect[2] 90 obb [rect[0][0], rect[0][1], rect[1][0], rect[1][1], angle]致命陷阱HRSC2016的角度定义与DOTA不同前者使用头部方向角需要额外90度修正2.2 处理标注冲突的三大原则当遇到标注文件与图像不匹配时优先校验机制用Pillow快速验证图像尺寸from PIL import Image img Image.open(image.png) assert img.size (800, 800) # DIOR数据集必须满足容错解析策略对破损XML文件使用lxml的recover模式类别映射表维护一个dataset_class_to_model_class的字典3. 框架适配实战3.1 YOLOv5的定制化改造要让YOLOv5支持旋转框需要修改以下核心文件数据加载dataset.pydef parse_dota_label(path): with open(path) as f: lines [x.strip() for x in f.readlines()] for line in lines: parts line.split() if len(parts) 9: continue *poly, cls, difficult parts # 处理DOTA的8点坐标 yield np.array(poly, dtypenp.float32), cls损失计算loss.py替换原有的IoU计算为旋转矩形IoU参考OpenCV的rotatedRectangleIntersection3.2 MMDetection的最佳实践对于FAIR1M这类大规模数据集推荐使用MMDetection的分布式加载# configs/_base_/datasets/fair1m.py dataset_type FAIR1MDataset data dict( samples_per_gpu4, # 根据显存调整 workers_per_gpu4, # 推荐等于CPU核心数 traindict( typedataset_type, ann_filetrain/labelXml/, img_prefixtrain/images/, pipelinetrain_pipeline), valdict(...), testdict(...))性能优化当遇到CUDA out of memory时尝试在pipelines中启用RandomCrop4. 常见报错解决方案库4.1 坐标越界错误症状出现Coordinate x810 exceeds image width 800修复方案# 在数据增强前添加边界检查 def clip_coords(boxes, img_shape): boxes[:, [0, 2]] boxes[:, [0, 2]].clip(0, img_shape[1]) # x boxes[:, [1, 3]] boxes[:, [1, 3]].clip(0, img_shape[0]) # y4.2 类别ID不连续症状RuntimeError: Class id 3 out of bounds根本原因某些数据集如NWPU VHR-10的类别ID从1开始计数解决方案# 在构建DataLoader时重映射ID class RemapDataset(torch.utils.data.Dataset): def __getitem__(self, idx): _, target self.dataset[idx] target[labels] - 1 # 1-based → 0-based return target4.3 内存泄漏排查当处理超大图像时watch nvidia-smi显示内存持续增长检查DataLoader的pin_memory设置用memory_profiler定位泄漏点profile def load_batch(batch): # 你的数据加载代码在实验室的Tesla V100上处理FAIR1M的10000×10000图像需要特别关注分块加载策略。我的经验是先将大图像预切割为1024×1024的网格并为每个网格生成对应的标注过滤——这能使显存占用从32GB降至8GB以下。