import json
import os
from lxml import etree
from collections import defaultdict
def create_voc_annotation(annotation_info, output_path):
annotation = etree.Element("annotation")
folder = etree.Element("folder")
folder.text = "VOC"
annotation.append(folder)
filename = etree.Element("filename")
filename.text = annotation_info["filename"]
annotation.append(filename)
size = etree.Element("size")
annotation.append(size)
width = etree.Element("width")
width.text = str(annotation_info["width"])
size.append(width)
height = etree.Element("height")
height.text = str(annotation_info["height"])
size.append(height)
depth = etree.Element("depth")
depth.text = "3"
size.append(depth)
for obj in annotation_info["objects"]:
object_item = etree.Element("object")
annotation.append(object_item)
name = etree.Element("name")
name.text = obj["name"]
object_item.append(name)
bndbox = etree.Element("bndbox")
object_item.append(bndbox)
xmin = etree.Element("xmin")
xmin.text = str(obj["bbox"][0])
bndbox.append(xmin)
ymin = etree.Element("ymin")
ymin.text = str(obj["bbox"][1])
bndbox.append(ymin)
xmax = etree.Element("xmax")
xmax.text = str(obj["bbox"][2])
bndbox.append(xmax)
ymax = etree.Element("ymax")
ymax.text = str(obj["bbox"][3])
bndbox.append(ymax)
with open(output_path, "wb") as f:
f.write(etree.tostring(annotation, pretty_print=True))
def coco_to_voc(coco_json_path, output_dir, categories):
with open(coco_json_path) as f:
coco_data = json.load(f)
id_to_category = {c["id"]: c["name"] for c in coco_data["categories"]}
annotations = defaultdict(list)
for ann in coco_data["annotations"]:
if ann["category_id"] in id_to_category:
image_id = ann["image_id"]
category_name = id_to_category[ann["category_id"]]
bbox = [
int(ann["bbox"][0]),
int(ann["bbox"][1]),
int(ann["bbox"][0] + ann["bbox"][2]),
int(ann["bbox"][1] + ann["bbox"][3]),
]
annotations[image_id].append({"name": category_name, "bbox": bbox})
id_to_filename = {img["id"]: img["file_name"] for img in coco_data["images"]}
for img_id, objects in annotations.items():
filename = id_to_filename[img_id]
image_info = {
"filename": filename,
"width": coco_data["images"][0]["width"],
"height": coco_data["images"][0]["height"],
"objects": objects,
}
output_path = os.path.join(output_dir, os.path.splitext(filename)[0] + ".xml")
create_voc_annotation(image_info, output_path)
def main():
coco_json_path = "E:/data/merge_test.json"
output_dir = "E:/data/train/Annotations"
categories = [f"class{i}" for i in range(1, 20)]
if not os.path.exists(output_dir):
os.makedirs(output_dir)
coco_to_voc(coco_json_path, output_dir, categories)
if __name__ == "__main__":
main()
# json_path = r"E:/data/train/merge_train.json"
# img_path = r"E:/data/train/train/"
# Annotations_save_path = r'E:/data/train/Annotations'