从Faster R-CNN到Oriented R-CNNDOTA数据集旋转目标检测全流程实战遥感图像中的舰船、建筑物或自动驾驶场景中的倾斜车辆这些目标往往不是规整的水平矩形框能完整框住的。传统目标检测方法在处理这类目标时要么会引入大量背景噪声要么无法准确描述目标的实际朝向和形状。这就是旋转目标检测技术要解决的核心问题。1. 旋转目标检测基础与环境搭建旋转目标检测与常规目标检测最大的区别在于边界框的表示方式。水平检测框通常用(x,y,w,h)表示中心点坐标和宽高而旋转框则需要引入角度参数。常见的旋转框表示方法有五点表示法(x1,y1,x2,y2,x3,y3,x4,y4)表示四个角点坐标旋转矩形表示(x,y,w,h,θ)其中θ表示旋转角度中点偏移表示(x,y,w,h,Δα,Δβ)通过偏移量描述旋转特性在DOTA数据集中标注采用四点表示法这对模型训练提出了特殊要求。我们选择MMRotate作为基础框架它是OpenMMLab系列中专门针对旋转目标检测的工具包。环境安装步骤conda create -n mmrotate python3.8 -y conda activate mmrotate pip install torch1.9.0cu111 torchvision0.10.0cu111 -f https://download.pytorch.org/whl/torch_stable.html pip install mmcv-full1.4.5 -f https://download.openmmlab.com/mmcv/dist/cu111/torch1.9.0/index.html git clone https://github.com/open-mmlab/mmrotate.git cd mmrotate pip install -r requirements/build.txt pip install -v -e .注意CUDA版本需要与PyTorch版本匹配否则会导致训练时出现难以排查的错误。2. DOTA数据集处理与特殊配置DOTA数据集是当前最大的航空图像旋转目标检测基准包含2,806张图像和188,282个实例涵盖15个类别。其特殊之处在于图像尺寸极大约4000×4000像素目标方向任意且密集排列标注采用四点坐标表示法数据处理关键步骤使用官方工具将原始图像切分为600×600的子图转换标注格式为MMRotate支持的格式处理类别不平衡问题如港口类比车辆少得多# 标注格式转换示例 def dotav2_to_mmrotate(ann_file, out_file): data_infos [] with open(ann_file) as f: data json.load(f) for img_info in data[images]: filename img_info[file_name] width img_info[width] height img_info[height] anns [obj for obj in data[annotations] if obj[image_id] img_info[id]] bboxes [] labels [] for ann in anns: bbox ann[bbox] # [x1,y1,x2,y2,x3,y3,x4,y4] label ann[category_id] bboxes.append(bbox) labels.append(label) data_infos.append({ filename: filename, width: width, height: height, ann: { bboxes: np.array(bboxes, dtypenp.float32), labels: np.array(labels, dtypenp.int64) } }) mmcv.dump(data_infos, out_file)3. Oriented R-CNN核心架构解析Oriented R-CNN在Faster R-CNN基础上进行了三处关键改进Oriented RPN生成带方向的候选框Rotated RoI Align旋转区域特征对齐中点偏移表示法更稳定的旋转框回归3.1 Oriented RPN设计细节传统RPN输出的是(x,y,w,h)四维回归量Oriented RPN则扩展为六维(x,y,w,h,Δα,Δβ)。这种设计避免了直接回归角度带来的边界不连续问题。Anchor设置对比参数传统RPNOriented RPNAnchor类型水平矩形水平矩形回归维度46角度处理无中点偏移计算复杂度低中等3.2 Rotated RoI Align实现这是模型中最关键也最容易出错的模块。其核心思想是根据预测的Δα和Δβ计算旋转矩阵对每个RoI区域进行旋转变换在旋转后的坐标系中进行双线性插值# Rotated RoI Align核心代码逻辑 def rotated_roi_align(features, rois, output_size): theta calculate_rotation(rois) # 从Δα,Δβ计算旋转角度 rotated_rois apply_rotation(rois, theta) grid generate_grid_points(rotated_rois, output_size) sampled_features bilinear_sample(features, grid) return sampled_features提示实际实现时要特别注意处理旋转后的边界情况避免特征图越界访问。4. 完整训练配置与调优策略以下是一个经过验证有效的训练配置方案基础配置# oriented_rcnn_r50_fpn_1x_dota_le90.py model dict( typeOrientedRCNN, backbonedict( typeResNet, depth50, num_stages4, out_indices(0, 1, 2, 3), frozen_stages1, norm_cfgdict(typeBN, requires_gradTrue), norm_evalTrue, stylepytorch), neckdict( typeFPN, in_channels[256, 512, 1024, 2048], out_channels256, num_outs5), rpn_headdict( typeOrientedRPNHead, in_channels256, feat_channels256, anchor_generatordict( typeAnchorGenerator, scales[8], ratios[0.5, 1.0, 2.0], strides[4, 8, 16, 32, 64]), bbox_coderdict( typeMidpointOffsetCoder), loss_clsdict( typeCrossEntropyLoss, use_sigmoidTrue, loss_weight1.0), loss_bboxdict( typeSmoothL1Loss, beta0.1111111111111111, loss_weight1.0)), roi_headdict( typeOrientedStandardRoIHead, bbox_roi_extractordict( typeRotatedSingleRoIExtractor, roi_layerdict( typeRoIAlignRotated, output_size7, sampling_ratio0), out_channels256, featmap_strides[4, 8, 16, 32]), bbox_headdict( typeRotatedShared2FCBBoxHead, in_channels256, fc_out_channels1024, roi_feat_size7, num_classes15, bbox_coderdict( typeDeltaXYWHABBoxCoder, target_means[0., 0., 0., 0., 0., 0.], target_stds[0.1, 0.1, 0.2, 0.2, 0.1, 0.1]), reg_class_agnosticTrue, loss_clsdict( typeCrossEntropyLoss, use_sigmoidFalse, loss_weight1.0), loss_bboxdict(typeSmoothL1Loss, beta1.0, loss_weight1.0))))调优经验学习率设置初始lr0.005每15个epoch下降10倍数据增强随机旋转(-30°,30°)范围效果最佳正负样本比例保持1:3可缓解类别不平衡多尺度训练短边随机选择[400,600,800]像素5. 模型评估与结果可视化DOTA数据集采用mAP(mean Average Precision)作为主要评估指标考虑不同IoU阈值下的检测精度。典型性能指标方法mAP0.5参数量(M)推理速度(FPS)Faster R-CNN58.241.512.3RoI Trans.69.845.29.7Oriented R-CNN75.643.111.2可视化分析时重点关注以下场景的检测效果密集排列的舰船不同朝向的车辆不规则形状的建筑群# 结果可视化代码示例 def show_results(img, bboxes, labels, class_names, score_thr0.5): plt.imshow(img) ax plt.gca() for bbox, label in zip(bboxes, labels): if bbox[8] score_thr: continue poly bbox[:8].reshape(4, 2) ax.add_patch(plt.Polygon( poly, fillFalse, edgecolorred, linewidth2)) text f{class_names[label]} {bbox[8]:.2f} ax.text(poly[0, 0], poly[0, 1], text, bboxdict(facecoloryellow, alpha0.5)) plt.show()在实际项目中我们发现模型对小角度旋转(±15°)的目标检测效果最好而对接近45°的目标容易出现偏差。这主要是因为数据集中这类样本较少可以通过针对性增加大角度样本的数据增强来改善。
从Faster R-CNN到Oriented R-CNN:在DOTA数据集上实战旋转目标检测(附完整训练配置)
发布时间:2026/5/29 6:06:54
从Faster R-CNN到Oriented R-CNNDOTA数据集旋转目标检测全流程实战遥感图像中的舰船、建筑物或自动驾驶场景中的倾斜车辆这些目标往往不是规整的水平矩形框能完整框住的。传统目标检测方法在处理这类目标时要么会引入大量背景噪声要么无法准确描述目标的实际朝向和形状。这就是旋转目标检测技术要解决的核心问题。1. 旋转目标检测基础与环境搭建旋转目标检测与常规目标检测最大的区别在于边界框的表示方式。水平检测框通常用(x,y,w,h)表示中心点坐标和宽高而旋转框则需要引入角度参数。常见的旋转框表示方法有五点表示法(x1,y1,x2,y2,x3,y3,x4,y4)表示四个角点坐标旋转矩形表示(x,y,w,h,θ)其中θ表示旋转角度中点偏移表示(x,y,w,h,Δα,Δβ)通过偏移量描述旋转特性在DOTA数据集中标注采用四点表示法这对模型训练提出了特殊要求。我们选择MMRotate作为基础框架它是OpenMMLab系列中专门针对旋转目标检测的工具包。环境安装步骤conda create -n mmrotate python3.8 -y conda activate mmrotate pip install torch1.9.0cu111 torchvision0.10.0cu111 -f https://download.pytorch.org/whl/torch_stable.html pip install mmcv-full1.4.5 -f https://download.openmmlab.com/mmcv/dist/cu111/torch1.9.0/index.html git clone https://github.com/open-mmlab/mmrotate.git cd mmrotate pip install -r requirements/build.txt pip install -v -e .注意CUDA版本需要与PyTorch版本匹配否则会导致训练时出现难以排查的错误。2. DOTA数据集处理与特殊配置DOTA数据集是当前最大的航空图像旋转目标检测基准包含2,806张图像和188,282个实例涵盖15个类别。其特殊之处在于图像尺寸极大约4000×4000像素目标方向任意且密集排列标注采用四点坐标表示法数据处理关键步骤使用官方工具将原始图像切分为600×600的子图转换标注格式为MMRotate支持的格式处理类别不平衡问题如港口类比车辆少得多# 标注格式转换示例 def dotav2_to_mmrotate(ann_file, out_file): data_infos [] with open(ann_file) as f: data json.load(f) for img_info in data[images]: filename img_info[file_name] width img_info[width] height img_info[height] anns [obj for obj in data[annotations] if obj[image_id] img_info[id]] bboxes [] labels [] for ann in anns: bbox ann[bbox] # [x1,y1,x2,y2,x3,y3,x4,y4] label ann[category_id] bboxes.append(bbox) labels.append(label) data_infos.append({ filename: filename, width: width, height: height, ann: { bboxes: np.array(bboxes, dtypenp.float32), labels: np.array(labels, dtypenp.int64) } }) mmcv.dump(data_infos, out_file)3. Oriented R-CNN核心架构解析Oriented R-CNN在Faster R-CNN基础上进行了三处关键改进Oriented RPN生成带方向的候选框Rotated RoI Align旋转区域特征对齐中点偏移表示法更稳定的旋转框回归3.1 Oriented RPN设计细节传统RPN输出的是(x,y,w,h)四维回归量Oriented RPN则扩展为六维(x,y,w,h,Δα,Δβ)。这种设计避免了直接回归角度带来的边界不连续问题。Anchor设置对比参数传统RPNOriented RPNAnchor类型水平矩形水平矩形回归维度46角度处理无中点偏移计算复杂度低中等3.2 Rotated RoI Align实现这是模型中最关键也最容易出错的模块。其核心思想是根据预测的Δα和Δβ计算旋转矩阵对每个RoI区域进行旋转变换在旋转后的坐标系中进行双线性插值# Rotated RoI Align核心代码逻辑 def rotated_roi_align(features, rois, output_size): theta calculate_rotation(rois) # 从Δα,Δβ计算旋转角度 rotated_rois apply_rotation(rois, theta) grid generate_grid_points(rotated_rois, output_size) sampled_features bilinear_sample(features, grid) return sampled_features提示实际实现时要特别注意处理旋转后的边界情况避免特征图越界访问。4. 完整训练配置与调优策略以下是一个经过验证有效的训练配置方案基础配置# oriented_rcnn_r50_fpn_1x_dota_le90.py model dict( typeOrientedRCNN, backbonedict( typeResNet, depth50, num_stages4, out_indices(0, 1, 2, 3), frozen_stages1, norm_cfgdict(typeBN, requires_gradTrue), norm_evalTrue, stylepytorch), neckdict( typeFPN, in_channels[256, 512, 1024, 2048], out_channels256, num_outs5), rpn_headdict( typeOrientedRPNHead, in_channels256, feat_channels256, anchor_generatordict( typeAnchorGenerator, scales[8], ratios[0.5, 1.0, 2.0], strides[4, 8, 16, 32, 64]), bbox_coderdict( typeMidpointOffsetCoder), loss_clsdict( typeCrossEntropyLoss, use_sigmoidTrue, loss_weight1.0), loss_bboxdict( typeSmoothL1Loss, beta0.1111111111111111, loss_weight1.0)), roi_headdict( typeOrientedStandardRoIHead, bbox_roi_extractordict( typeRotatedSingleRoIExtractor, roi_layerdict( typeRoIAlignRotated, output_size7, sampling_ratio0), out_channels256, featmap_strides[4, 8, 16, 32]), bbox_headdict( typeRotatedShared2FCBBoxHead, in_channels256, fc_out_channels1024, roi_feat_size7, num_classes15, bbox_coderdict( typeDeltaXYWHABBoxCoder, target_means[0., 0., 0., 0., 0., 0.], target_stds[0.1, 0.1, 0.2, 0.2, 0.1, 0.1]), reg_class_agnosticTrue, loss_clsdict( typeCrossEntropyLoss, use_sigmoidFalse, loss_weight1.0), loss_bboxdict(typeSmoothL1Loss, beta1.0, loss_weight1.0))))调优经验学习率设置初始lr0.005每15个epoch下降10倍数据增强随机旋转(-30°,30°)范围效果最佳正负样本比例保持1:3可缓解类别不平衡多尺度训练短边随机选择[400,600,800]像素5. 模型评估与结果可视化DOTA数据集采用mAP(mean Average Precision)作为主要评估指标考虑不同IoU阈值下的检测精度。典型性能指标方法mAP0.5参数量(M)推理速度(FPS)Faster R-CNN58.241.512.3RoI Trans.69.845.29.7Oriented R-CNN75.643.111.2可视化分析时重点关注以下场景的检测效果密集排列的舰船不同朝向的车辆不规则形状的建筑群# 结果可视化代码示例 def show_results(img, bboxes, labels, class_names, score_thr0.5): plt.imshow(img) ax plt.gca() for bbox, label in zip(bboxes, labels): if bbox[8] score_thr: continue poly bbox[:8].reshape(4, 2) ax.add_patch(plt.Polygon( poly, fillFalse, edgecolorred, linewidth2)) text f{class_names[label]} {bbox[8]:.2f} ax.text(poly[0, 0], poly[0, 1], text, bboxdict(facecoloryellow, alpha0.5)) plt.show()在实际项目中我们发现模型对小角度旋转(±15°)的目标检测效果最好而对接近45°的目标容易出现偏差。这主要是因为数据集中这类样本较少可以通过针对性增加大角度样本的数据增强来改善。