AI-TOD 数据集整理
本文档详细记录了AI-TOD遥感小目标检测数据集的完整整理流程,包含数据下载、处理和格式转换三个阶段。首先从xView和AI-TOD_wo_xview两个数据源获取基础素材,通过官方合成脚本生成9306张训练图像。随后将VOC格式标注转换为YOLO标准格式,包括类别提取、坐标归一化等步骤,并生成适配YOLO框架的配置文件。整个流程规范可复现,确保了数据完整性(图像数量、标注准确)和格式兼容性(支持
本文档用于归档 AI-TOD 遥感小目标检测数据集的完整整理流程,涵盖数据下载、数据处理、格式转换三个核心阶段,流程规范可复现,适配后续 YOLO/MMDetection 等框架的模型训练需求。
一、 数据下载(阶段 1)
1.1 下载所需数据集
AI-TOD 数据集的生成依赖两个核心数据源,需分别下载并归档:
- xView 原始数据集(小目标素材库)
- 下载地址:xView 官方发布渠道(或学术数据集平台如 Kaggle)需注册(https://challenge.xviewdataset.org/profile)
- 归档内容:下载得到
的压缩包、解压后的 846 张遥感图像(.tif 格式)、官方标注文件 xView_train.geojson - 归档路径:
/media/lfq/EAGET/AI-TOD/AI-TOD/xview/(统一存放,方便后续调用) - 关键说明:xView 数据集仅需训练集(846 张),无需测试集,其核心价值是提供带精准标注的小目标图像块。
2. AI-TOD_wo_xview 数据集(基础背景画布库)
- 下载地址:https://drive.google.com/drive/folders/1uNY_rcOO5LrWibXRY6l2dvqSbK6xikJp
- 归档内容:下载得到的压缩包、解压后的标注文件(.json 格式,存放至
annotations目录)、图像文件(.png 格式,按 train/val/test 三级目录存放) - 归档路径:
/media/lfq/EAGET/AI-TOD/AI-TOD/aitod/(保持官方指定目录结构不变) - 关键说明:该数据集是 AI-TOD 的基础背景库,图像数量分别为 train 7510 张、val 2804 张、test 9351 张,无需修改其目录结构,避免影响后续合成流程。
1.2 下载配套工具
- AI-TOD 官方合成脚本:从 AI-TOD 官方 GitHub 仓库下载
generate_aitod_imgs.py及相关配置文件,归档路径:/media/lfq/EAGET/AI-TOD/AI-TOD/ - wwtool 工具库:用于地理数据 / 标注格式处理,后续若需简化操作可安装,克隆地址:
https://github.com/jwwangchn/wwtool.git
1.3 环境准备
- 激活专属 Conda 环境:
conda activate aitod(Python 3.7,适配 AI-TOD 相关工具依赖) - 预装基础依赖:
pip install numpy pillow tqdm shapely fiona(为后续数据处理、格式转换铺路)
二、 数据处理(阶段 2)
2.1 数据解压与目录规整
- 分别解压 xView 数据集和 AI-TOD_wo_xview 数据集,确保解压后目录结构符合以下规范,无冗余压缩包:
├─aitod │ ├─annotations ## put the downloaded annotations of AI-TOD_wo_xview (.json) │ └─images ## unzip the downloaded AI-TOD_wo_xview image sets, put them (.png) in the corresponding folder │ ├─test ## directly put the images in it without extra folder │ ├─train │ ├─trainval │ └─val ├─aitod_xview ## here are six files (.txt) ├─xview │ ├─ori │ │ └─train_images ## unzip the downloaded xView training set images, put them (.tif) here │ └─xView_train.geojson ## the annotation file of xView training set └─generate_aitod_imgs.py ## end-to-end tool核对目录完整性:
- xView 目录:
xview/ori/train_images/包含 846 张 .tif 图像,xview/下存在xView_train.geojson标注,无缺失文件。 - AI-TOD_wo_xview 目录:
aitod/annotations/包含完整 .json 标注,aitod/images/下 train/val/test 三级结构完整,图像数量分别为 7510/2804/9351 张,无损坏图像。 aitod_xview/目录:包含 6 个 .txt 文件,无缺失、无损坏
2.2 运行 AI-TOD 数据合成脚本
核心目标:将 xView 小目标素材嵌入 AI-TOD_wo_xview 背景图像,生成完整的 AI-TOD 数据集(9306 张,train/3704 张、val/935 张、test/4667 张)。
切换至脚本目录:cd /media/lfq/EAGET/AI-TOD/AI-TOD/
1. 准备wwtool工具
git clone https://github.com/jwwangchn/wwtool.git
cd wwtool
python setup.py develop
安装其他重要的包
cd ..
cd aitodtoolkit
pip install -r requirements.txt
运行运行合成脚本:
python generate_aitod_imgs.py
2. 监控运行日志:无报错中断、无缺失文件提示,等待合成完成(耗时根据硬件配置有所差异)。
3. 验证合成结果:
查看输出目录 /media/lfq/EAGET/AI-TOD/AI-TOD/aitodtoolkit/xview/xview_aitod_sets/,确认存在 train/val/test 三级目录。
随机打开若干图像,检查小目标嵌入自然,无明显拼接痕迹,图像无损坏。
核对图像数量:train 3704 张、val 935 张、test 4667 张,总数 9306 张,符合官方标准。
2.3 原始标注归档
合成完成后,将生成的原始标注(VOC 风格 .txt 格式,分布在 train/val/test 三级目录下)分别归档至对应目录的 ./voc_anno/ 文件夹,路径示例:
- train 集标注:
./xview/xview_aitod_sets/train/voc_anno/ - val 集标注:
./xview/xview_aitod_sets/val/voc_anno/ - test 集标注:
./xview/xview_aitod_sets/test/voc_anno/确保标注文件与图像文件一一对应(同名,仅后缀不同),无缺失、无冗余。
三、 数据格式转换(阶段 3)
核心目标:将 VOC 风格 .txt 标注(xmin ymin xmax ymax class_name)转换为 YOLO 标准格式 .txt 标注(class_id x_center y_center w h,归一化至 0-1),适配 YOLOv5/YOLOv8 等框架训练。
3.1 步骤 1:提取全量类别(多目录批量提取)
- 新建辅助脚本
extract_classes_multi_dir.py,配置 train/val/test 三级标注目录路径(对应./xview/xview_aitod_sets/下的三级 voc_anno 目录)。 - 运行脚本:
python extract_classes_multi_dir.py - 提取结果归档:
- 记录提取到的全量类别数量(与 AI-TOD 官方 28 类核对,确保无遗漏)。
- 复制脚本输出的
CLASS_MAP(类别 - 数字 ID 映射表,ID 从 0 开始连续排列),归档至文档,方便后续复用。 - 记录各类别标注数量及分布(train/val/test),判断数据均衡性,归档统计结果。
import os
# ---------------------- 配置区(修改为你的三个标注目录路径)----------------------
# 填写 train、val、test 三个目录的完整路径(按你的实际路径修改)
VOC_TXT_DIRS = [
"/media/lfq/EAGET/AI-TOD/AI-TOD/aitodtoolkit/xview/xview_aitod_sets/trainval/labels",
"/media/lfq/EAGET/AI-TOD/AI-TOD/aitodtoolkit/xview/xview_aitod_sets/test/labels",
]
# --------------------------------------------------------------------------------
# 1. 初始化数据结构(去重+统计)
class_set = set() # 存储所有不重复类别
class_count_total = {} # 统计所有目录的总标注数量
class_count_per_dir = {} # 统计每个目录的标注数量(方便查看分布)
# 2. 遍历所有指定目录
for voc_txt_dir in VOC_TXT_DIRS:
# 初始化当前目录的类别统计
dir_name = os.path.basename(os.path.dirname(voc_txt_dir)) # 提取目录名(train/val/test)
class_count_per_dir[dir_name] = {}
# 检查目录是否存在
if not os.path.exists(voc_txt_dir):
print(f"警告:目录不存在,跳过 → {voc_txt_dir}")
continue
# 遍历当前目录下的所有 .txt 标注文件
voc_txt_files = [f for f in os.listdir(voc_txt_dir) if f.endswith(".txt")]
if not voc_txt_files:
print(f"警告:目录下无 .txt 标注文件,跳过 → {voc_txt_dir}")
continue
# 解析每个标注文件
for txt_file in voc_txt_files:
txt_path = os.path.join(voc_txt_dir, txt_file)
with open(txt_path, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line:
continue # 跳过空行
# 解析每行标注(格式:xmin ymin xmax ymax class_name)
parts = line.split()
if len(parts) != 5:
continue # 跳过格式错误的行
# 提取类别名称
class_name = parts[-1]
# 3. 加入全局集合(自动去重)
class_set.add(class_name)
# 4. 统计总数量
if class_name in class_count_total:
class_count_total[class_name] += 1
else:
class_count_total[class_name] = 1
# 5. 统计当前目录的数量
if class_name in class_count_per_dir[dir_name]:
class_count_per_dir[dir_name][class_name] += 1
else:
class_count_per_dir[dir_name][class_name] = 1
# 3. 转换为有序列表(方便分配 YOLO 类别 ID)
class_list = sorted(list(class_set))
# 4. 输出结果
print("=" * 60)
print(f"成功从 {len([d for d in VOC_TXT_DIRS if os.path.exists(d)])} 个有效目录中提取到 {len(class_list)} 个类别:")
print("=" * 60)
# 输出所有类别(带全局序号和总数量)
for idx, class_name in enumerate(class_list):
total_count = class_count_total.get(class_name, 0)
print(f"类别 ID {idx} → {class_name}(总标注数量:{total_count})")
# 输出每个目录的类别分布(可选,方便查看数据均衡性)
print("\n" + "=" * 60)
print("各目录类别标注数量分布:")
print("=" * 60)
for dir_name, class_count in class_count_per_dir.items():
print(f"\n【{dir_name} 目录】")
for class_name in class_list:
dir_count = class_count.get(class_name, 0)
print(f" {class_name}:{dir_count} 条标注")
# 输出可直接复制的 CLASS_MAP
print("\n" + "=" * 60)
print("直接可复制到 VOC → YOLO 转换脚本的 CLASS_MAP:")
print("=" * 60)
class_map_code = "CLASS_MAP = {\n"
for idx, class_name in enumerate(class_list):
class_map_code += f' "{class_name}": {idx},\n'
class_map_code = class_map_code.rstrip(",\n") + "\n}"
print(class_map_code)
3.2 步骤 2:批量转换标注格式
- 新建转换脚本
voc_txt2yolo_txt.py,粘贴步骤 1 中提取的CLASS_MAP,配置图像尺寸 1024x1024。 - 分三次运行脚本(分别对应 train/val/test 集),每次修改脚本中「输入 VOC 标注目录」和「输出 YOLO 标注目录」:
- train 集转换:输入
./xview/xview_aitod_sets/train/voc_anno/,输出./xview/xview_aitod_sets/train/yolo_anno/ - val 集转换:输入
./xview/xview_aitod_sets/val/voc_anno/,输出./xview/xview_aitod_sets/val/yolo_anno/ - test 集转换:输入
./xview/xview_aitod_sets/test/voc_anno/,输出./xview/xview_aitod_sets/test/yolo_anno/
- train 集转换:输入
- 运行命令:
python voc_txt2yolo_txt.py,监控无「未知类别」警告、无格式错误警告。
import os
from tqdm import tqdm
# ---------------------- 配置区(必须根据你的实际情况修改)----------------------
# 1. 你的 VOC 风格 .txt 标注文件夹路径
input_voc_txt_dir = "/media/lfq/EAGET/AI-TOD/AI-TOD/aitodtoolkit/xview/xview_aitod_sets/trainval/labels" # 替换为你的 VOC .txt 文件夹路径
# 2. YOLO 格式 .txt 标注输出文件夹路径
output_yolo_txt_dir = "/media/lfq/EAGET/AI-TOD/AI-TOD/aitodtoolkit/xview/xview_aitod_sets/trainval/yolo-labels"
# 3. AI-TOD 图像尺寸(默认 1024x1024,无需修改,若不同请调整)
IMG_WIDTH, IMG_HEIGHT = 1024, 1024
# 4. 类别映射表(key:你的 VOC 标注中的文本类别,value:YOLO 数字 ID(从 0 开始))
# 示例:如果你的标注只有 "vehicle" 类,就只保留这一行;有多个类就依次添加
CLASS_MAP = {
"airplane": 0,
"ship": 1,
"storage-tank": 2,
"vehicle": 3
}
# --------------------------------------------------------------------------------
# 1. 确保输出目录存在
os.makedirs(output_yolo_txt_dir, exist_ok=True)
# 2. 遍历所有 VOC 风格 .txt 标注文件
voc_txt_files = [f for f in os.listdir(input_voc_txt_dir) if f.endswith(".txt")]
if not voc_txt_files:
print("错误:未在输入目录中找到 .txt 标注文件")
exit(1)
for txt_file in tqdm(voc_txt_files, desc="转换 VOC → YOLO"):
# 2.1 拼接输入/输出文件路径
input_txt_path = os.path.join(input_voc_txt_dir, txt_file)
output_txt_path = os.path.join(output_yolo_txt_dir, txt_file)
# 2.2 读取 VOC 标注,转换并写入 YOLO 标注
with open(input_txt_path, 'r', encoding='utf-8') as f_in, \
open(output_txt_path, 'w', encoding='utf-8') as f_out:
for line in f_in:
line = line.strip()
if not line:
continue # 跳过空行
# 解析 VOC 格式一行数据(xmin ymin xmax ymax class_name)
# 注意:如果你的数据有多余空格/制表符,split() 会自动处理
parts = line.split()
if len(parts) != 5:
print(f"警告:跳过无效行(格式错误)→ {line}")
continue
xmin, ymin, xmax, ymax, class_name = parts
# 2.3 转换为数值类型(像素坐标)
try:
xmin = float(xmin)
ymin = float(ymin)
xmax = float(xmax)
ymax = float(ymax)
except ValueError:
print(f"警告:跳过无效行(坐标非数字)→ {line}")
continue
# 2.4 检查类别是否在映射表中
if class_name not in CLASS_MAP:
print(f"警告:跳过未知类别 → {class_name}")
continue
class_id = CLASS_MAP[class_name]
# 2.5 转换为 YOLO 格式(归一化 + 中心坐标+宽高)
# 计算中心坐标
x_center = (xmin + xmax) / 2.0
y_center = (ymin + ymax) / 2.0
# 计算宽高
bbox_w = xmax - xmin
bbox_h = ymax - ymin
# 归一化(除以图像宽高,保留 6 位小数)
x_center_norm = round(x_center / IMG_WIDTH, 6)
y_center_norm = round(y_center / IMG_HEIGHT, 6)
bbox_w_norm = round(bbox_w / IMG_WIDTH, 6)
bbox_h_norm = round(bbox_h / IMG_HEIGHT, 6)
# 2.6 写入 YOLO 标注文件
f_out.write(f"{class_id} {x_center_norm} {y_center_norm} {bbox_w_norm} {bbox_h_norm}\n")
# 3. 转换完成提示
print(f"\n转换成功!YOLO 标注文件已保存至:{output_yolo_txt_dir}")
print(f"共处理 {len(voc_txt_files)} 个标注文件")
3.3 步骤 3:验证转换结果
- 核对标注文件:输出目录下 YOLO 标注文件与输入 VOC 标注文件、图像文件一一对应,数量一致。
- 核对标注格式:
- 打开任意 YOLO 标注文件,内容为「class_id 四个归一化数值」,数值范围 0-1,保留 6 位小数。
- 随机选取 1-2 个标注文件,手动验证坐标转换正确性(通过 VOC 坐标反推 YOLO 坐标,确认无计算错误)。
- 归档转换结果:将 train/val/test 三级目录下的 YOLO 标注文件永久归档,路径与图像文件对应,方便后续模型训练调用。
3.4 步骤 4:生成 YOLO 框架配置文件
新建 aitod.yaml 配置文件,填写数据集路径、类别信息,归档至 ./xview/xview_aitod_sets/ 目录,内容示例:
path: /media/lfq/EAGET/AI-TOD/AI-TOD/aitodtoolkit/xview/xview_aitod_sets # 数据集根路径
train: train # 训练集图像目录(相对根路径)
val: val # 验证集图像目录(相对根路径)
test: test # 测试集图像目录(相对根路径)
nc: 4 # 类别总数(AI-TOD 官方 28 类)
names: ["airplane", "ship", "storage-tank","vehicle"] # 完整类别名称列表(与 CLASS_MAP 一一对应)
四、 最终归档与总结
- 完整目录结构归档:将整理后的 AI-TOD 数据集按「图像 + VOC 标注 + YOLO 标注 + 配置文件」的结构归档,确保目录清晰、路径可追溯。
- 文档归档:将本文档、辅助脚本、转换脚本、类别统计结果、配置文件统一归档至
./docs/目录,方便后续团队复用、复现实验。 - 关键结论:
- 本次整理的 AI-TOD 数据集符合官方标准,图像数量 9306 张,标注完整、格式正确。
- 转换后的 YOLO 格式标注可直接用于 YOLO 系列框架训练,无需额外处理。
- 数据集小目标密集,适配遥感小目标检测任务,后续训练需针对性优化模型参数与数据增强策略。
总结
- AI-TOD 数据集整理核心分为「下载、处理、格式转换」三阶段,需保证数据源完整、合成流程无报错、格式转换精准,同时严格遵循修正后的目录结构与路径要求。
- 数据处理的关键是运行官方合成脚本,生成符合标准的 9306 张图像并存放至指定路径
xview_aitod_sets;格式转换的核心是「类别提取 - 映射 - 坐标归一化」,适配目标训练框架。 - 全程需做好目录规整与结果归档,确保流程可复现、数据可追溯,为后续模型训练奠定坚实基础。
更多推荐



所有评论(0)