MMRotate训练遥感小目标?从DOTA数据集裁剪到模型调优的全流程实战
2026/6/10 11:19:45 网站建设 项目流程

MMRotate遥感小目标检测实战:从数据裁剪到模型调优的完整指南

遥感图像中的小目标检测一直是计算机视觉领域的难点。当目标尺寸仅为几十像素甚至更小时,常规检测方法往往难以奏效。本文将基于MMRotate框架,分享一套针对DOTA等遥感数据集的完整解决方案,涵盖数据预处理、模型选择、参数调优等关键环节。

1. 遥感小目标检测的核心挑战

1920x1080像素的航拍图像中,一栋建筑可能只占据50x30像素的区域。这种目标与背景的极端不平衡带来了三个典型问题:

  • 特征提取困难:小目标在卷积过程中容易丢失细节信息
  • 正负样本失衡:背景区域远多于有效目标区域
  • 定位精度不足:旋转框的倾斜角度增加了回归难度

以DOTA数据集为例,其图像尺寸普遍在4000x4000像素以上,但车辆等目标的最小外接矩形宽度可能不足15像素。直接输入原始图像会导致:

# 典型遥感图像尺寸与目标尺寸对比 image_size = (4000, 4000) # 1600万像素 target_size = (15, 8) # 120像素,占比仅0.00075%

2. 数据预处理:智能裁剪策略

2.1 分块裁剪的必要性

MMRotate提供的img_split.py脚本通过滑动窗口实现大图切割,其核心参数包括:

参数名推荐值作用说明
patch_size1024输出图像块尺寸
overlap200相邻块重叠区域
image_ext.png输出图像格式
rate_thr0.7有效区域保留阈值

实际操作中建议采用重叠分块策略

python tools/data/dota/split/img_split.py \ --base_json configs/split_configs/custom_train.json \ --patch_size 1024 \ --overlap 200

注意:overlap值应大于目标最大尺寸的1.5倍,避免目标被切割

2.2 标签转换与验证

使用roLabelImg标注时需特别注意角度定义规则。推荐转换脚本包含以下关键步骤:

  1. 解析XML中的旋转框参数(cx,cy,w,h,angle)
  2. 计算四个角点坐标
  3. 按DOTA格式排序点集(左上角开始顺时针)
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

验证转换结果时,建议可视化检查边界框是否准确包裹目标:

3. 模型架构调优策略

3.1 锚框(Anchor)优化配置

针对小目标的锚框设置需要调整三个关键维度:

  1. 尺度(scale): 典型值[8,16,32]适用于常规目标,小目标应改为[4,8,16]
  2. 长宽比(ratio): 遥感目标常见比例[1,1.5,2,3,5]
  3. 角度(angle): 建议每45°设置一个锚框,共8个方向
# MMRotate中的anchor生成配置 anchor_generator=dict( type='RotatedAnchorGenerator', scales=[4, 8, 16], ratios=[1.0, 1.5, 2.0, 3.0, 5.0], strides=[4, 8, 16, 32, 64], angles=[0, 45, 90, 135])

3.2 特征金字塔(FPN)增强

在mmrotate/configs/base/models/faster_rcnn_r50_fpn.py中修改:

# 增加P2层获取更高分辨率特征 fpn=dict( in_channels=[256, 512, 1024, 2048], out_channels=256, start_level=1, # 原为2 num_outs=5) # 原为4 # ROI Align设置 roi_head=dict( featmap_strides=[4, 8, 16, 32]) # 对应FPN输出

4. 训练参数调优实战

4.1 学习率与批次大小

基于裁剪后数据特点,推荐采用渐进式学习率策略:

# 在configs/base/schedules/schedule_1x.py中修改 optimizer = dict( type='SGD', lr=0.01, # 基础学习率 momentum=0.9, weight_decay=0.0001) lr_config = dict( policy='step', warmup='linear', warmup_iters=500, warmup_ratio=0.001, step=[8, 11]) # 在第8和11epoch时衰减

4.2 数据增强方案

针对小目标的特殊增强策略:

train_pipeline = [ dict(type='LoadImageFromFile'), dict(type='LoadAnnotations', with_bbox=True), dict(type='RResize', img_scale=(1024, 1024)), dict( type='RRandomFlip', flip_ratio=0.5, direction=['horizontal', 'vertical']), dict( type='PolyRandomRotate', rotate_ratio=0.5, angles_range=180, auto_bound=False), dict(type='BrightnessTransform', level=10), dict(type='ContrastTransform', level=10), dict(type='HSVAugment', hgain=5, sgain=5, vgain=5), dict(type='Normalize', **img_norm_cfg), dict(type='Pad', size_divisor=32), dict(type='DefaultFormatBundle'), dict(type='Collect', keys=['img', 'gt_bboxes']) ]

5. 性能优化与结果分析

5.1 典型评估指标对比

在DOTA-v1.5测试集上的实验结果:

模型mAP@0.5小目标召回率推理速度(FPS)
R-50-FPN62.345.112.3
R-101-FPN64.748.29.8
R3Det68.253.67.5

5.2 显存优化技巧

当遇到CUDA out of memory错误时,可尝试以下调整:

  1. 减小批次大小:

    data = dict( samples_per_gpu=2, # 原为4 workers_per_gpu=2)
  2. 使用梯度累积:

    optimizer_config = dict( type='GradientCumulativeOptimizerHook', cumulative_iters=2)
  3. 混合精度训练:

    fp16 = dict( loss_scale=512., grad_clip=dict(max_norm=35, norm_type=2))

在实际项目中,针对2000x2000像素的航拍图像,经过1024x1024分块处理后,使用R3Det模型训练时单个GPU的显存占用从18GB降至6GB,使GTX 1080Ti等消费级显卡也能胜任训练任务。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询