【目标检测】旋转目标检测COCO格式标注转DOTAv1格式
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() # 跳过文件开头的imagesource和gsd信息 for line in lines[2:]: # 开始处理从第三行起的标注信息 parts = line.strip().split(' ') if len(parts)
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。