遥感图像中的目标检测一直是计算机视觉领域的重要课题。与常规水平框检测不同,旋转目标检测能够更精确地定位建筑物、车辆等具有方向性的目标。本文将基于MMRotate框架,分享一个完整的遥感目标检测项目实战经验,涵盖数据预处理、模型训练、调优技巧等关键环节。
遥感图像通常具有大尺寸、非方形比例的特点,直接输入模型训练会导致显存不足和性能下降。合理的数据预处理是项目成功的第一步。
roLabelImg是旋转目标标注的利器,支持旋转矩形框标注。标注时需要注意:
python复制def rotatePoint(xc, yc, xp, yp, theta):
xoff = xp - xc
yoff = yp - yc
cosTheta = math.cos(theta)
sinTheta = math.sin(theta)
pResx = cosTheta * xoff + sinTheta * yoff
pResy = -sinTheta * xoff + cosTheta * yoff
return xc + pResx, yc + pResy
大尺寸遥感图像需要裁剪为适合模型输入的尺寸,img_split.py脚本提供了灵活的裁剪配置:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| image_ext | .png | 建议统一转换为PNG格式 |
| patch_size | 1024 | 平衡显存占用与目标完整性 |
| overlap | 200 | 避免目标被切割 |
| iof_thr | 0.7 | 保留足够的目标区域 |
实际项目中,我们发现以下配置组合效果最佳:
json复制{
"image_ext": ".png",
"patch_size": 1024,
"overlap": 256,
"iof_thr": 0.75,
"no_padding": false
}
MMRotate提供了多种旋转检测模型,针对遥感目标特点,我们选择Rotated Faster R-CNN作为基础架构。
rotated_faster_rcnn_r50_fpn_x1_dota_le90.py需要调整的核心参数:
python复制model = dict(
roi_head=dict(
bbox_head=dict(
num_classes=1, # 根据实际类别数调整
loss_bbox=dict(type='RotatedIoULoss', loss_weight=1.0)
)
),
train_cfg=dict(
rpn=dict(
nms_pre=2000,
max_per_img=2000
)
)
)
提示:对于小目标密集场景,可适当增加nms_pre和max_per_img值
遥感图像需要特殊的数据增强组合:
python复制train_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='LoadAnnotations', with_bbox=True),
dict(type='RotatedRandomFlip', flip_ratio=0.5),
dict(type='RandomRotate', rate=0.5, angles=[30, 60, 90, 120]),
dict(type='BrightnessTransform', level=10),
dict(type='ContrastTransform', level=10),
dict(type='Normalize'),
dict(type='Pad', size_divisor=32),
dict(type='DefaultFormatBundle'),
dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels'])
]
遇到"CUDA out of memory"错误时,可采取以下措施:
python复制data = dict(
samples_per_gpu=2, # 根据GPU显存调整
workers_per_gpu=2 # 根据CPU核心数调整
)
python复制optimizer_config = dict(grad_clip=dict(max_norm=35, norm_type=2), cumulative_iters=4)
针对遥感数据特点,我们采用warmup+余弦退火的学习率策略:
python复制lr_config = dict(
policy='CosineAnnealing',
warmup='linear',
warmup_iters=500,
warmup_ratio=1.0/3,
min_lr=1e-6
)
optimizer = dict(
type='SGD',
lr=0.005, # 初始学习率
momentum=0.9,
weight_decay=0.0001
)
MMRotate提供了全面的评估指标,重点关注:
在实际项目中,我们遇到并解决了以下典型问题:
python复制rpn_head=dict(
anchor_generator=dict(
scales=[4, 8, 16, 32], # 针对不同大小目标调整
ratios=[0.5, 1.0, 2.0],
strides=[4, 8, 16, 32, 64]
)
)
python复制test_cfg=dict(
rpn=dict(
nms_pre=2000,
max_per_img=2000,
nms=dict(type='nms', iou_threshold=0.7),
min_bbox_size=0
),
rcnn=dict(
score_thr=0.05, # 提高可减少误检
nms=dict(type='nms', iou_threshold=0.1),
max_per_img=2000
)
)
python复制neck=dict(
type='FPN',
in_channels=[256, 512, 1024, 2048],
out_channels=256,
num_outs=5 # 增加特征金字塔层数
),
roi_head=dict(
bbox_roi_extractor=dict(
type='SingleRoIExtractor',
roi_layer=dict(
type='RoIAlignRotated',
out_size=7,
sample_num=2 # 增加采样点
)
)
)