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)