【目标检测】旋转目标检测COCO格式标注转DOTAv1格式

本文介绍了如何将COCO格式的标注转换为DOTA格式,包含imagesource和gsd信息,并提供了一个脚本实现标注可视化。脚本展示了如何处理多边形,计算旋转边界框,以及批量处理图像和DOTA标注文件以展示标注结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DOTAv1数据集格式:

'imagesource':imagesource
'gsd':gsd
x1, y1, x2, y2, x3, y3, x4, y4, category, difficult
x1, y1, x2, y2, x3, y3, x4, y4, category, difficult
...

imagesource: 图片来源  
gsd: 分辨率
x1, y1, x2, y2, x3, y3, x4, y4:四边形的四个顶点的坐标 顶点按顺时针顺序排列,第一个起点为左上第一个点
category:实例类别
difficult:表示该实例是否难以检测(1表示困难,0表示不困难)

COCO转DOTA:

import json
import cv2
import numpy as np
import os

def calculate_rotated_bbox(poly):
    """将多边形坐标转换为旋转边界框"""
    contour = np.array(poly).reshape((-1, 1, 2)).astype(np.float32)
    rect = cv2.minAreaRect(contour)
    box = cv2.boxPoints(rect)
    return np.int0(box)

def coco_to_dota(coco_annotation_path, dota_annotation_folder, imagesource="Unknown", gsd="Unknown"):
    """将COCO格式的标注转换为DOTA格式,包括imagesource和gsd信息"""
    # 类别ID到名称的映射
    category_map = {
        1: 'Class1',
        2: 'Class2',
    }

    # 确保输出目录存在
    if not os.path.exists(dota_annotation_folder):
        os.makedirs(dota_annotation_folder)

    # 读取COCO格式的JSON文件
    with open(coco_annotation_path, 'r') as f:
        coco_data = json.load(f)

    # 遍历每个图像的标注
    for image in coco_data['images']:
        image_id = image['id']
        image_filename = image['file_name']
        dota_filename = os.path.splitext(image_filename)[0] + '.txt'  # 去掉原始扩展名,添加.txt
        dota_filepath = os.path.join(dota_annotation_folder, dota_filename)

        with open(dota_filepath, 'w') as dota_file:
            # 写入imagesource和gsd信息
            # dota_file.write(f"'imagesource':{imagesource}\n'gsd':{gsd}\n")

            # 找到当前图像的所有标注
            for annotation in filter(lambda x: x['image_id'] == image_id, coco_data['annotations']):
                if 'segmentation' in annotation:
                    for seg in annotation['segmentation']:
                        if type(seg[0]) is list:  # 检查是否是多边形格式
                            seg = seg[0]
                        box = calculate_rotated_bbox(seg)
                        # 从映射中获取类别名称
                        category_name = category_map.get(annotation['category_id'], 'Unknown')
                        # 格式化DOTA标注
                        box_str = ' '.join(map(str, box.flatten().tolist()))
                        dota_annotation = f"{box_str} {category_name} 0\n"
                        dota_file.write(dota_annotation)


# 调用函数,转换COCO到DOTA
coco_annotation_path = 'instances.json'
dota_annotation_folder = 'dota'
coco_to_dota(coco_annotation_path, dota_annotation_folder)

标注可视化:

import cv2
import numpy as np
import os


def draw_rotated_box(img, box, label):
    """在图像上绘制旋转的边界框和标签。"""
    points = np.int0(box)
    cv2.drawContours(img, [points], 0, (0, 255, 0), 2)  # 绘制旋转框
    cv2.putText(img, label, tuple(points[0]), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)  # 添加文本标签


def visualize_dota_annotations(image_folder, annotation_folder, output_folder):
    """批量处理图像和DOTA标注文件,绘制旋转边界框和标签"""
    # 确保输出文件夹存在
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    # 遍历图像文件
    for img_filename in os.listdir(image_folder):
        img_path = os.path.join(image_folder, img_filename)
        if os.path.isfile(img_path) and img_filename.endswith(('.jpg', '.png')):
            annot_filename = os.path.splitext(img_filename)[0] + '.txt'
            annot_path = os.path.join(annotation_folder, annot_filename)
            output_img_path = os.path.join(output_folder, img_filename)

            img = cv2.imread(img_path)
            if img is None:
                continue

            if os.path.isfile(annot_path):
                with open(annot_path, 'r') as f:
                    lines = f.readlines()  # Skip imagesource and gsd lines
                    for line in lines:
                        parts = line.strip().split(' ')
                        if len(parts) < 9:
                            continue
                        box = np.array([float(part) for part in parts[:8]]).reshape(4, 2)
                        label = parts[8]
                        draw_rotated_box(img, box, label)

            cv2.imwrite(output_img_path, img)

# 路径配置
image_folder = 'images'
annotation_folder = 'dota'
output_folder = 'visual'

visualize_dota_annotations(image_folder, annotation_folder, output_folder)

<think>好的,用户想复现基于HRSC2016数据集的遥感目标检测模型训练与实验结果。首先,我需要整理步骤,确保覆盖数据准备、环境配置、模型选择、训练配置和结果验证这些关键环节。 首先,数据集的获取和处理是基础。HRSC2016数据集是高分辨率的舰船检测数据集,用户需要从官方渠道下载,并按照标准格式组织,比如VOC或COCO格式。可能需要检查数据集是否包含标注文件,如XML或JSON,并确认图像和标注的对应关系。此外,预处理步骤比如图像归一化、尺寸调整或数据增强(如旋转、翻)也很重要,特别是对于遥感图像常见的角度变化问题。 接下来是训练环境的搭建。用户可能使用PyTorch或TensorFlow架,需要安装相应的库,比如MMDetection或者Detectron2,这些架提供了预配置的模型和训练脚本。需要提醒用户注意版本兼容性,比如CUDA和cuDNN的版本是否匹配,以及依赖库是否正确安装。 然后是模型的选择。根据引用[1],当数据集较小时,使用轻量级主干网络可能更有效,避免依赖预训练权重。比如可以建议用户尝试ResNet变体或者更小的网络结构,同时结合FPN(特征金字塔网络)来提升检测效果。另外,设计适合旋转目标检测的模型结构,比如加入旋转边界的预测头,可能对HRSC2016数据集效果更好。 训练配置方面,需要设置合适的学习率、批次大小和优化器。由于数据集较小,过大的学习率可能导致模型不收敛,建议使用较小的初始学习率,并配合学习率衰减策略。同时,数据增强技术如随机裁剪、多尺度训练可以帮助提升模型的泛化能力。根据引用[3],用户可能需要修改配置文件中的数据集路径和参数,比如在dotav1.py中调整data_root,类似地处理HRSC2016的配置文件。 在训练过程中,监控损失函数和验证集指标是关键。如果发现过拟合,可以增加正则化方法如Dropout或权重衰减,或者使用早停策略。另外,引用[1]提到,随着网络层数增加,检测结果可能提升,但需要平衡模型复杂度和数据量,避免过拟合。 结果复现部分,用户需要运行验证脚本,使用测试集评估mAP等指标。对比引用[1]中的结果,检查是否达到预期性能。如果结果不符,可能需要调整超参数或检查数据预处理是否正确。此外,可视化检测结果可以帮助直观判断模型的表现,比如边界是否准确,尤其是处理旋转目标时。 可能遇到的问题包括数据集路径错误、标注格式不匹配、显存不足等。需要建议用户逐步排查,比如使用小批量数据测试,确保数据加载无误。另外,引用[2]提到的HRSID数据集的处理方法可能提供参考,比如如何处理不同分辨率的图像,或者多任务学习(检测、分割)的设置,但用户当前专注于HRSC2016,所以可能需要简化处理。 最后,生成的相关问题需要围绕用户可能的后续步骤,比如数据增强方法、模型调参、处理小数据集技巧,以及评估指标的选择。这些能帮助用户深入解决复现过程中遇到的挑战,并优化模型性能。</think>根据您的研究需求,以下是基于HRSC2016数据集的遥感目标检测模型训练与复现的详细步骤: --- ### 一、数据准备与处理 1. **数据集获取** - 通过官方渠道获取HRSC2016数据集,包含高分辨率遥感图像及标注文件(通常为XML格式) - 数据集特点:舰船目标、旋转边界标注、多尺度目标分布[^1] 2. **数据预处理** ```python # 示例:将旋转标注换为模型输入格式(如COCO格式) import xml.etree.ElementTree as ET def parse_hrsc_annotation(xml_path): tree = ET.parse(xml_path) objs = tree.findall('HRSC_Objects/HRSC_Object') bboxes = [] for obj in objs: cx = float(obj.find('mbox_cx').text) cy = float(obj.find('mbox_cy').text) w = float(obj.find('mbox_w').text) h = float(obj.find('mbox_h').text) angle = float(obj.find('mbox_ang').text) # 换为旋转参数或水平坐标 return bboxes ``` 3. **数据增强策略** - 针对遥感图像特性采用: - 随机旋转($[-15°,15°]$) - 多尺度训练($512\times512$至$1024\times1024$) - 色彩抖动(亮度、对比度调整) --- ### 二、训练环境搭建 1. **架选择** 推荐使用MMDetection或PaddleDetection等开源架: ```bash # MMDetection安装示例 conda create -n detect python=3.8 conda activate detect pip install openmim mim install mmengine mmcv mmdet ``` 2. **模型选择** - 优先选择旋转目标检测模型: - Rotated Faster R-CNN - S2A-Net - ReDet(专门针对遥感数据的旋转检测网络)[^1] --- ### 三、模型训练配置 1. **配置文件修改** ```python # 以MMRotate为例修改configs/rotated_faster_rcnn/r50_fpn_1x_hrsc.py data_root = 'data/HRSC2016/' train_dataloader = dict( dataset=dict( ann_file='trainval.txt', data_prefix=dict(img_path='FullDataSet/Images/') )) ``` 需匹配实际文件路径结构(参考引用[3]中dotav1.py的修改方法) 2. **训练参数设置** ```python optimizer = dict(type='SGD', lr=0.005, momentum=0.9, weight_decay=0.0001) lr_config = dict(policy='step', step=[8, 11]) total_epochs = 12 ``` --- ### 四、训练与验证 1. **启动训练** ```bash python tools/train.py configs/rotated_faster_rcnn/r50_fpn_1x_hrsc.py ``` 2. **性能验证** ```bash python tools/test.py configs/rotated_faster_rcnn/r50_fpn_1x_hrsc.py work_dirs/latest.pth ``` 预期达到的指标范围:mAP@0.5在75%-85%之间(依模型复杂度不同)[^1] --- ### 五、关键问题解决方案 | 常见问题 | 解决方法 | |---------|----------| | 显存不足 | 减小`batch_size`,使用`fp16`训练 | | 标注格式不匹配 | 使用`tools/dataset_converters/hrsc2dota.py`换工具 | | 收敛困难 | 尝试加载ImageNet预训练权重(小数据集建议保留随机初始化[^1]) | --- ### 六、结果复现验证 1. 对比论文指标时应确保: - 使用相同的训练/验证集划分 - 相同的评估协议(IoU阈值、是否考虑旋转角度) 2. 可视化检测结果: ```python from mmdet.apis import inference_detector, show_result_pyplot model = init_detector(config_file, checkpoint_file) result = inference_detector(model, 'test_image.jpg') show_result_pyplot(model, 'test_image.jpg', result) ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值