从零构建MMRotate旋转检测实战:自定义数据集标注、训练与调优全解析
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 python3.8 -y conda activate mmrotate conda install pytorch1.7.1 torchvision0.8.2 cudatoolkit10.2 -c pytorch2.2 MMRotate全家桶安装安装顺序很关键我踩过的坑包括mmcv-full版本不匹配导致无法导入mmdetection版本过高引发API冲突推荐使用这套组合pip install mmcv-full1.4.5 -f https://download.openmmlab.com/mmcv/dist/cu102/torch1.7.1/index.html pip install mmdet2.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.pymodel dict( roi_headdict( bbox_headdict( num_classes1))) # 修改为你的类别数调整学习率策略optimizer dict( lr0.005, # 根据batch size调整 paramwise_cfgdict( bias_lr_mult2., # 偏置项加倍学习率 norm_decay_mult0.))4.2 常见训练问题解决CUDA out of memory除了调小batch size还可以启用梯度累积optimizer_config dict( cumulative_iters4) # 每4个iter更新一次使用混合精度训练fp16 dict(loss_scale512.)Loss震荡严重尝试增加warmup迭代lr_config dict( warmup_iters500, warmup_ratio0.001)调整正负样本比例train_cfg dict( rpndict( samplerdict( num256, pos_fraction0.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_fileos.path.join(out_dir, img))5.2 后处理优化策略调整NMS阈值test_cfg dict( rcnndict( nmsdict( iou_threshold0.1))) # 密集目标可降低到0.05启用多尺度测试img_norm_cfg dict( transforms[ dict(typeMultiScaleFlipAug, scales[(1333, 768), (1333, 800)], flipTrue) ])在实际项目中通过调整这些参数我将船舶检测的AP从0.68提升到了0.82。关键是要根据验证集指标进行针对性优化不同场景的最佳参数组合可能差异很大。