1. DIOR数据集与YOLO格式适配概述
DIOR(Dataset for Object dectectIOn in Remote sensing images)是遥感图像目标检测领域的标杆级数据集,包含23,463张图像和192,472个标注实例,涵盖20个常见地物类别。这个数据集最大的特点是所有图像均来自谷歌地球的高分辨率卫星影像(0.5m-30m分辨率),场景覆盖全球不同地域的城乡区域。
将DIOR适配YOLO格式的核心挑战在于标注体系的转换。原始DIOR采用PASCAL VOC格式的XML标注文件,而YOLO要求的是每个图像对应一个.txt文件,其中每行表示一个对象,格式为:
code复制<class_id> <x_center> <y_center> <width> <height>
这些坐标需要是归一化后的相对值(0-1之间)。此外,YOLO对图像输入尺寸有特定要求(默认640x640),而DIOR原始图像尺寸不统一(800x800居多),需要进行resize或letterbox处理。
关键提示:遥感图像与常规自然图像不同,长宽比差异大且小目标密集,直接套用常规YOLO预处理会导致目标变形或检测性能下降。建议优先采用letterbox方式保持原图比例。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 完整转换流程详解
2.1 环境准备与数据下载
推荐使用Python 3.8+环境,主要依赖库:
bash复制pip install numpy pandas opencv-python tqdm xmltodict
DIOR数据集官方下载地址需通过邮件申请(含train/val/test集),解压后目录结构应为:
code复制DIOR/
├── Annotations/
├── JPEGImages/
├── ImageSets/
│ ├── Main/
│ │ ├── train.txt
│ │ └── val.txt
└── ...
2.2 标注格式转换脚本
以下Python脚本实现VOC转YOLO格式的核心逻辑:
python复制import os
import xml.etree.ElementTree as ET
def convert(size, box):
""" 将VOC坐标转换为YOLO格式 """
dw = 1./size[0]
dh = 1./size[1]
x = (box[0] + box[1])/2.0
y = (box[2] + box[3])/2.0
w = box[1] - box[0]
h = box[3] - box[2]
x = x * dw
w = w * dw
y = y * dh
h = h * dh
return (x,y,w,h)
def convert_annotation(xml_path, classes):
tree = ET.parse(xml_path)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
objects = []
for obj in root.iter('object'):
cls = obj.find('name').text
if cls not in classes:
continue
cls_id = classes.index(cls)
bndbox = obj.find('bndbox')
b = (float(bndbox.find('xmin').text),
float(bndbox.find('xmax').text),
float(bndbox.find('ymin').text),
float(bndbox.find('ymax').text))
bb = convert((w,h), b)
objects.append(f"{cls_id} {' '.join([str(a) for a in bb])}")
return objects
2.3 类别映射处理
DIOR的20个原始类别需要映射为连续ID(0-19):
python复制classes = [
'airplane', 'airport', 'baseballfield', 'basketballcourt',
'bridge', 'chimney', 'dam', 'Expressway-Service-area',
'Expressway-toll-station', 'golffield', 'groundtrackfield',
'harbor', 'overpass', 'ship', 'stadium', 'storagetank',
'tenniscourt', 'trainstation', 'vehicle', 'windmill'
]
3. 图像预处理专项优化
3.1 遥感图像特性处理
由于卫星影像的特殊性,需特别注意:
- 多光谱通道处理:DIOR含RGB三通道图像,若需使用红外等额外波段需单独处理
- 大尺寸图像切割:原始800x800图像可切割为640x640子图提升小目标检测效果
- 方向校正:部分地物(如船舶、车辆)具有方向性,可考虑添加旋转增强
3.2 Letterbox处理实现
保持原图比例的resize方法(YOLOv5/v8默认方式):
python复制def letterbox(im, new_shape=(640, 640), color=(114, 114, 114)):
# 调整图像大小并保持纵横比
shape = im.shape[:2] # 当前形状 [height, width]
if isinstance(new_shape, int):
new_shape = (new_shape, new_shape)
# 计算比例 (new / old)
r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
# 计算padding
new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]
# 均分padding到两侧
dw /= 2
dh /= 2
# 执行resize
if shape[::-1] != new_unpad:
im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)
# 添加border
top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
im = cv2.copyMakeBorder(im, top, bottom, left, right,
cv2.BORDER_CONSTANT, value=color)
return im, r, (dw, dh)
4. YOLO训练配置建议
4.1 数据集YAML文件
创建dior.yaml配置文件:
yaml复制path: ../DIOR-YOLO # 数据集根目录
train: images/train # 训练集路径
val: images/val # 验证集路径
# 类别列表
names:
0: airplane
1: airport
...
19: windmill
4.2 超参数优化建议
针对遥感目标特点调整:
yaml复制# YOLOv8示例配置
lr0: 0.01 # 初始学习率(卫星图像复杂度高,可适当增大)
lrf: 0.01 # 最终学习率
weight_decay: 0.0005
warmup_epochs: 3.0
box: 7.5 # 加大box loss权重(小目标密集)
cls: 0.5 # 分类损失权重
hsv_h: 0.015 # 色相增强幅度(减小,遥感图像色彩敏感)
hsv_s: 0.7 # 饱和度增强
hsv_v: 0.4 # 明度增强
degrees: 10.0 # 旋转增强(重要!)
translate: 0.1 # 平移增强
scale: 0.9 # 尺度缩放
5. 常见问题解决方案
5.1 标注偏移问题
现象:转换后检测框位置不准确
解决方法:
- 检查归一化计算是否溢出(坐标值应在0-1之间)
- 验证图像读取与标注的尺寸一致性
- 对于切割后的子图,需同步调整标注坐标
5.2 类别不平衡处理
DIOR中各类别样本量差异大(如'windmill'仅891例,'vehicle'有14,336例):
- 采用oversampling策略
- 使用focal loss
- 调整class权重:
python复制# 计算类别权重
from sklearn.utils.class_weight import compute_class_weight
class_weights = compute_class_weight('balanced', classes=range(20), y=train_labels)
5.3 小目标检测优化
针对遥感图像中的小目标(<32x32像素):
- 修改anchor尺寸:
python复制# YOLOv8 anchors(针对800x800图像调整)
anchors:
- [5,6, 8,14, 15,11] # P3/8
- [10,13, 16,30, 33,23] # P4/16
- [30,61, 62,45, 59,119] # P5/32
- 使用更高分辨率的检测头(如从640x640提升到1024x1024)
- 添加小目标专用检测层(借鉴YOLOv8-SmallObject改进)
6. 模型部署实践
6.1 边缘设备部署示例(以K230为例)
python复制# 模型转换(PyTorch -> ONNX -> nncase)
import torch
model = torch.load('yolov8n-dior.pt')
model.export(format='onnx', imgsz=[640,640])
# nncase编译命令
./ncc compile yolov8n-dior.onnx k230_yolov8.kmodel \
--input-format onnx \
--output-format kmodel \
--input-shape "1,3,640,640" \
--input-type float32 \
--output-type float32 \
--dataset ./calib_dataset \
--inference-type float
6.2 多路视频流处理
使用多线程处理摄像头输入:
python复制from threading import Thread
import queue
class StreamProcessor:
def __init__(self, rtsp_urls, model_path):
self.queues = [queue.Queue(maxsize=1) for _ in rtsp_urls]
self.model = YOLO(model_path)
def capture_thread(self, url, q):
cap = cv2.VideoCapture(url)
while True:
ret, frame = cap.read()
if not ret: continue
if q.empty(): # 只保留最新帧
q.put(frame)
def process(self):
while True:
frames = []
for q in self.queues:
if not q.empty():
frames.append(q.get())
if frames:
results = self.model(frames, stream=True)
# 后处理逻辑...
在实际部署中发现,DIOR数据集训练的模型对低空无人机影像也有良好迁移效果,这得益于其多样的视角和光照条件。一个实用技巧是在模型微调阶段加入10%的模糊和雾化增强,能显著提升复杂天气条件下的鲁棒性。
