Coco格式Json文件转换成xml文件

修改coco_dir,json_path, save_dir,即图片位置,json位置,xml保存位置(自动创建,无需自建)

import cv2
import numpy as np
import os
import json
from collections import defaultdict
from xml.etree.ElementTree import Element, SubElement, tostring
import xml.dom.minidom as md


def create_xml_annotation(image_name, image_width, image_height, objects):
    annotation = Element("annotation")

    folder = SubElement(annotation, "folder")
    folder.text = "images"

    filename = SubElement(annotation, "filename")
    filename.text = image_name

    size = SubElement(annotation, "size")
    width = SubElement(size, "width")
    width.text = str(image_width)
    height = SubElement(size, "height")
    height.text = str(image_height)
    depth = SubElement(size, "depth")
    depth.text = "3"  # Assuming RGB images

    for obj in objects:
        obj_elem = SubElement(annotation, "object")
        name = SubElement(obj_elem, "name")
        name.text = obj['class']
        bndbox = SubElement(obj_elem, "bndbox")
        xmin = SubElement(bndbox, "xmin")
        xmin.text = str(obj['xmin'])
        ymin = SubElement(bndbox, "ymin")
        ymin.text = str(obj['ymin'])
        xmax = SubElement(bndbox, "xmax")
        xmax.text = str(obj['xmax'])
        ymax = SubElement(bndbox, "ymax")
        ymax.text = str(obj['ymax'])

    xml_str = tostring(annotation, encoding="unicode")
    xml_str = xml_str.replace('><', '>\n<')

    return xml_str


def cocojson2png_rectangles_xml(coco_dir, json_path, save_dir):
    save_path = os.path.join(save_dir)
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    annotation_file = os.path.join(coco_dir, 'annotations', json_path)
    with open(annotation_file, 'r', encoding='utf-8') as annf:
        annotations = json.load(annf)
        images = [i['id'] for i in annotations['images']]

    img_anno = defaultdict(list)
    for anno in annotations['annotations']:
        for img_id in images:
            if anno['image_id'] == img_id:
                img_anno[img_id].append(anno)
    imgid_file = {}
    for im in annotations['images']:
        imgid_file[im['id']] = im['file_name']

    for img_idx in img_anno:
        image = cv2.imread(os.path.join(coco_dir,  imgid_file[img_idx]))
        h, w, _ = image.shape
        instance_rectangles = []  # 存储矩形锚框
        for idx, ann in enumerate(img_anno[img_idx]):
            mask = np.zeros((h, w), dtype=np.uint8)
            for an in ann['segmentation']:
                ct = np.expand_dims(np.array(an), 0).astype(int)
                contour = np.stack((ct[:, ::2], ct[:, 1::2])).T
                cv2.fillPoly(mask, [contour], 1)

            # 找到分割区域的外接矩形
            x, y, width, height = cv2.boundingRect(mask)
            instance_rectangles.append({
                'class': str(ann['category_id']),
                'xmin': str(x),
                'ymin': str(y),
                'xmax': str(x + width),
                'ymax': str(y + height)
            })

        # 生成 XML 内容
        xml_content = create_xml_annotation(
            image_name=imgid_file[img_idx],
            image_width=w,
            image_height=h,
            objects=instance_rectangles
        )

        # 保存 XML 文件
        xml_filename = os.path.join(save_path, imgid_file[img_idx].split('.')[0] + ".xml")
        with open(xml_filename, 'w') as xml_file:
            xml_file.write(xml_content)


if __name__ == '__main__':
    # 修改coco_dir json_path save_dir,图片位置,json位置,xml保存位置(自动创建,无需自建) 
    coco_dir = r"D:\StudyAPP\PyCharm2023\Projects\PreData\train"
    json_path = r"D:\StudyAPP\PyCharm2023\Projects\PreData\instances_train_trashcan.json"
    save_dir = r'D:\StudyAPP\PyCharm2023\Projects\PreData\xml_rectangles'
    cocojson2png_rectangles_xml(coco_dir, json_path, save_dir)


Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐