json文件转xml

之前对阿里比赛的一个数据集格式进行转换,数据集是瓶装白酒瑕疵品检测,数据集瓶装酒的瑕疵分为3个大类:瓶盖瑕疵、标贴瑕疵、喷码瑕疵,以下列举部分瑕疵示例图像。

图像都存放在images文件夹,图像后缀为.jpg。标注文件为annotations.json。标注采用类似MSCOCO数据集的标注格式(http://cocodataset.org),数据结构如下:

{
"images":
[
{"file_name":"cat.jpg", "id":1, "height":1000, "width":1000},
{"file_name":"dog.jpg", "id":2, "height":1000, "width":1000},

]
"annotations":
[
{"image_id":1, "bbox":[100.00, 200.00, 10.00, 10.00], "category_id": 1}
{"image_id":2, "bbox":[150.00, 250.00, 20.00, 20.00], "category_id": 2}

]
"categories":
[
{"id":0, "name":"bg"}
{"id":1, "name":"cat"}
{"id":2, "name":"dog"}

]
}

标注文件中,"images" 关键字对应图片信息;

"annotations" 关键字对应标注信息;

"categories" 对应类别信息:

"images": 该关键字对应的数据中,每一项对应一张图片,"file_name"对应图片名称,"id"对应图片序号,"height""width"分别对应图像的高和宽。

"annotations": 该关键字对应的数据中,每一项对应一条标注,"image_id"对应图片序号,"bbox"对应标注矩形框,顺序为[x, y, w, h],分别为该矩形框的起始点x坐标,起始点y坐标,宽、高(左上角坐标,宽高)。"category_id"对应类别序号。

"categories": 该关键字对应的数据中,每一项对应一个类别,"id"对应类别序号,"name"对应类别名称。

关键字关联说明:

  1. "annotations"中的元素通过"image_id"关联图像,比如"image_id":2,该条标注信息对应"images""id"为2的图像。
  2. "annotations"中的元素通过"category_id"关联类别,比如"category_id":2,该条标注信息对应"categories""id"为2的类别。

例: 在上面列出的数据结构中

{"image_id":1, "bbox":[100.00, 200.00, 10.00, 10.00], "category_id": 1}

这条标注信息通过"image_id"可以找到对应的图像为"cat.jpg",通过"category_id"可以找到对应的类别为"cat"

背景图片说明:

"annotations"中的元素,"category_id":0对应的是背景。当且仅当一张图片对应的所有annotations中,"category_id"都为0,该图片为背景图片。

代码如下:

# .txt-->.xml
# ! /usr/bin/python
# -*- coding:UTF-8 -*-
import os
import cv2
import json

def json_to_xml(data, img_path, xml_path):
    # 1.字典对标签中的类别进行转换
    dict = {
        '0': "background",
        '1': "Broken bottle cap",
        '2': "Bottle cap deformation",
        '3': "Broken edge of bottle cap",
        '4': "Bottle cap spinning",
        '5': "Cap breakpoint",
        '6': "Label skew",
        '7': "Label wrinkled",
        '8': "Label bubble",
        '9': "Code spraying is normal",
        '10': "Code spraying is not normal"
    }
    # 用于存储 "老图"
    pre_img_name = ''
    # 3.遍历文件夹
    for id, name in data_dic.items():
        print(name)
        img_name = name[:-4]
        pic = cv2.imread(img_path + name)
        # 获取图像大小信息
        Pheight, Pwidth, Pdepth = pic.shape
        for ann in data['annotations']:
            if id == ann['image_id']:
            # 遇到的是一张新图片
                if ann['image_id'] != pre_img_name:
                    # 6.新建xml文件
                    xml_file = open((xml_path + img_name + '.xml'), 'w')
                    xml_file.write('<annotation>\n')
                    xml_file.write('    <folder>VOC2007</folder>\n')
                    xml_file.write('    <filename>' + name + '</filename>\n')
                    xml_file.write('<source>\n')
                    xml_file.write('<database>orgaquant</database>\n')
                    xml_file.write('<annotation>organoids</annotation>\n')
                    xml_file.write('</source>\n')
                    xml_file.write('    <size>\n')
                    xml_file.write('        <width>' + str(Pwidth) + '</width>\n')
                    xml_file.write('        <height>' + str(Pheight) + '</height>\n')
                    xml_file.write('        <depth>' + str(Pdepth) + '</depth>\n')
                    xml_file.write('    </size>\n')
                    xml_file.write('            <segmented>0</segmented>\n')
                    xml_file.write('    <object>\n')
                    xml_file.write('<name>' + dict[str(ann['category_id'])] + '</name>\n')
                    xml_file.write('                    <pose>Unspecified</pose>\n')
                    xml_file.write('                    <truncated>0</truncated>\n')
                    xml_file.write('                    <difficult>0</difficult>\n')
                    xml_file.write('        <bndbox>\n')
                    xml_file.write('            <xmin>' + str(int(ann['bbox'][0])) + '</xmin>\n')
                    xml_file.write('            <ymin>' + str(int(ann['bbox'][1])) + '</ymin>\n')
                    xml_file.write('            <xmax>' + str(int(ann['bbox'][0] + ann['bbox'][2])) + '</xmax>\n')
                    xml_file.write('            <ymax>' + str(int(ann['bbox'][1] + ann['bbox'][3])) + '</ymax>\n')
                    xml_file.write('        </bndbox>\n')
                    xml_file.write('    </object>\n')
                    xml_file.close()
                    pre_img_name = ann['image_id']  # 将其设为"老"图
                else:  # 不是新图而是"老图"
                    # 7.同一张图片,只需要追加写入object
                    xml_file = open((xml_path + img_name + '.xml'), 'a')
                    xml_file.write('    <object>\n')
                    xml_file.write('<name>' + dict[str(ann['category_id'])] + '</name>\n')
                    xml_file.write('        <bndbox>\n')
                    xml_file.write('            <xmin>' + str(int(ann['bbox'][0])) + '</xmin>\n')
                    xml_file.write('            <ymin>' + str(int(ann['bbox'][1])) + '</ymin>\n')
                    xml_file.write('            <xmax>' + str(int(ann['bbox'][0]+ann['bbox'][2])) + '</xmax>\n')
                    xml_file.write('            <ymax>' + str(int(ann['bbox'][1]+ann['bbox'][3])) + '</ymax>\n')
                    xml_file.write('        </bndbox>\n')
                    xml_file.write('    </object>\n')
                    xml_file.close()

        # 8.读完txt文件最后写入</annotation>
        xml_file1 = open((xml_path + img_name + '.xml'), 'a')
        xml_file1.write('</annotation>')
        xml_file1.close()
    print("Done !")


# 修改成自己的文件夹 注意文件夹最后要加上/
if __name__ == '__main__':
    f = open('annotations.json', encoding='utf-8')
    data = json.load(f)
    data_dic = {}
    # 把图片名和id对应起来存到字典中
    for img in data['images']:
        data_dic[img['id']] = img['file_name'].strip()
    json_to_xml(data,"images/", "XML/")

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值