1. 为什么需要旋转目标检测?
在传统的目标检测任务中,我们通常使用水平矩形框来标注物体。但在遥感图像、自动驾驶、文档分析等场景下,物体往往呈现各种角度的旋转。比如卫星图像中的飞机、停车场里的车辆、扫描文档中的文字等,如果强行用水平框标注,会包含大量背景噪声,严重影响检测精度。
旋转框检测的核心优势在于能够更紧密地贴合物体轮廓。我曾在遥感图像分析项目中对比过两种标注方式:使用旋转框的检测准确率比水平框高出23%,特别是在密集小目标场景下优势更加明显。MMRotate作为OpenMMLab生态中的旋转检测专用工具箱,集成了Faster R-CNN、R3Det等主流算法,支持DOTA格式数据集,是处理这类任务的利器。
2. 环境配置与工具安装
2.1 基础环境搭建
实测在Ubuntu 20.04和Windows 10下都能稳定运行,建议优先选择Linux环境。需要准备:
- Python 3.7+(实测3.8最稳定)
- PyTorch 1.7+(与CUDA版本匹配)
- CUDA 10.1/10.2(根据显卡驱动选择)
- GCC 5+(编译mmcv-full必需)
具体安装命令如下:
conda create -n mmrotate python=3.8 -y conda activate mmrotate conda install pytorch==1.7.1 torchvision==0.8.2 cudatoolkit=10.2 -c pytorch2.2 MMRotate全家桶安装
安装顺序很关键,我踩过的坑包括:
- mmcv-full版本不匹配导致无法导入
- mmdetection版本过高引发API冲突
推荐使用这套组合:
pip install mmcv-full==1.4.5 -f https://download.openmmlab.com/mmcv/dist/cu102/torch1.7.1/index.html pip install mmdet==2.19.0 git clone https://github.com/open-mmlab/mmrotate.git cd mmrotate pip install -r requirements/build.txt pip install -v -e .验证安装成功的小技巧:运行python demo/image_demo.py时,如果能看到带旋转框的可视化结果,说明环境配置正确。
3. 自定义数据集制作全流程
3.1 旋转标注神器roLabelImg
不同于常规的labelImg,这个工具支持旋转矩形标注。安装时注意:
- 需要PyQt5环境
- 快捷键A/D切换标注,Z/X调整角度
- 务必保存为PASCAL VOC格式的XML文件
标注时有个关键细节:角度定义是w边(初始水平边)与x轴的顺时针夹角,范围限制在[-90°,90°]。我刚开始标注时没注意这个规则,导致后续转换出现框体错位。建议先在简单图像上测试,确认标注框能正确包裹目标。
3.2 格式转换核心代码解析
MMRotate要求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这个函数实现了关键点旋转计算,配合OpenCV的绘图函数可以可视化验证转换是否正确。建议在转换脚本中加入校验环节,用不同颜色绘制原始框和转换后的框体。
3.3 数据集划分与裁剪技巧
遥感图像通常尺寸较大,直接训练会爆显存。MMRotate提供了智能裁剪方案:
- 修改
split_configs/ss_train.json中的参数:
{ "image_dir": "your_images", "ann_dir": "your_labels", "save_dir": "split_results", "patch_size": [1024, 1024], "overlap_size": [200, 200] }- 运行裁剪脚本:
python tools/data/dota/split/img_split.py --base_json split_configs/ss_train.json重叠区域(overlap)设置很关键,太小会导致目标被切割,太大会增加计算量。根据目标尺寸调整,一般设置为目标平均大小的1/3。
4. 模型训练实战技巧
4.1 配置文件深度调优
以Faster R-CNN为例,关键修改点:
- 修改
configs/rotated_faster_rcnn/rotated_faster_rcnn_r50_fpn_1x_dota_le90.py:
model = dict( roi_head=dict( bbox_head=dict( num_classes=1))) # 修改为你的类别数- 调整学习率策略:
optimizer = dict( lr=0.005, # 根据batch size调整 paramwise_cfg=dict( bias_lr_mult=2., # 偏置项加倍学习率 norm_decay_mult=0.))4.2 常见训练问题解决
CUDA out of memory:除了调小batch size,还可以:
- 启用梯度累积:
optimizer_config = dict( cumulative_iters=4) # 每4个iter更新一次- 使用混合精度训练:
fp16 = dict(loss_scale=512.)Loss震荡严重:尝试:
- 增加warmup迭代:
lr_config = dict( warmup_iters=500, warmup_ratio=0.001)- 调整正负样本比例:
train_cfg = dict( rpn=dict( sampler=dict( num=256, pos_fraction=0.5)))5. 模型测试与效果提升
5.1 测试脚本定制化
官方demo不支持批量测试,可以改造为:
from mmrotate.apis import inference_detector, init_detector model = init_detector(config_file, checkpoint_file) for img in os.listdir(img_dir): result = inference_detector(model, os.path.join(img_dir, img)) show_result_pyplot(model, img, result, out_file=os.path.join(out_dir, img))5.2 后处理优化策略
- 调整NMS阈值:
test_cfg = dict( rcnn=dict( nms=dict( iou_threshold=0.1))) # 密集目标可降低到0.05- 启用多尺度测试:
img_norm_cfg = dict( transforms=[ dict(type='MultiScaleFlipAug', scales=[(1333, 768), (1333, 800)], flip=True) ])在实际项目中,通过调整这些参数,我将船舶检测的AP从0.68提升到了0.82。关键是要根据验证集指标进行针对性优化,不同场景的最佳参数组合可能差异很大。