json转labelimg标注的xml文件

比赛只给了json文件,需要转成xml文件

首先需要一个labelimg标注好的xml文件做模板,格式如下:

<annotation verified="no">
  <folder>train</folder>
  <filename>000000</filename>
  <path>D:/study/PycharmProjects/cv&#38646;&#22522;&#30784;/input/train/000000.png</path>
  <source>
    <database>Unknown</database>
  </source>
  <size>
    <width>741</width>
    <height>350</height>
    <depth>3</depth>
  </size>
  <segmented>0</segmented>
  <object>
    <name>1</name>
    <pose>Unspecified</pose>
    <truncated>0</truncated>
    <Difficult>0</Difficult>
    <bndbox>
      <xmin>259</xmin>
      <ymin>77</ymin>
      <xmax>320</xmax>
      <ymax>272</ymax>
    </bndbox>
  </object>
</annotation>

需要修改的地方有:

  1. filename
  2. size节点下的width、height、depth
  3. object节点下的name(标签名)
  4. object节点下的bndbox下的xmin、ymin、xmax、ymax

比赛提供的json格式如下:

{'000000.png': {'height': [30.0],
  'label': [5],
  'left': [43.0],
  'top': [7.0],
  'width': [19.0]},
 '000001.png': {'height': [23, 23, 23],
  'label': [2, 1, 0],
  'left': [99, 114, 121],
  'top': [5, 8, 6],
  'width': [14, 8, 12]},
 '000002.png': {'height': [16.0],
  'label': [6],
  'left': [61.0],
  'top': [6.0],
  'width': [11.0]}}

其中字符的具体坐标如下:
json转labelimg标注的xml文件_第1张图片

注意:这里与labelimg标注的xml中xmin、xmax、ymin、ymax有所不同
xmin = left
ymin = top
xmax = left + width
ymax = top + height

具体实现:

import os, json
import copy
from lxml.etree import Element, SubElement, tostring, ElementTree
import cv2
import numpy as np

template_file = '../input/xml/anno.xml' # xml模板
target_dir = '../input/xml/Annotations/' #保存路径
image_dir = '../input/val/'  # 图片文件夹
train_file = '../input/val.json'  # 存储了图片信息的json文件

# 提取json
def parse_json(d):
    arr = np.array([
        d['top'], d['height'], d['left'],  d['width'], d['label']
    ])
    arr = arr.astype(int)
    arr = arr.astype(str)
    return arr

trainfiles  = json.load(open(train_file))
tree = ElementTree()

for k, line in enumerate(trainfiles):
    arr = parse_json(trainfiles[line])
    file_name = line  #文件名
    for i in range(arr.shape[1]):
        if i == 0:
            label = arr[4, i]  # 标签名
            # 坐标
            ymin = arr[0, i]
            ymax = str(int(arr[0, i]) + int(arr[1, i]))  #
            xmin = arr[2, i]
            xmax = str(int(arr[2, i]) + int(arr[3, i]))
	
            tree.parse(template_file) # 解析树
            root = tree.getroot() # 根节点
            root.find('filename').text = file_name

            # size
            sz = root.find('size')
            im = cv2.imread(image_dir + file_name)#读取图片信息

            sz.find('height').text = str(im.shape[0])
            sz.find('width').text = str(im.shape[1])
            sz.find('depth').text = str(im.shape[2])
			
			# object
            obj = root.find('object')
            obj.find('name').text = label
            bb = obj.find('bndbox')
            bb.find('xmin').text = xmin
            bb.find('ymin').text = ymin
            bb.find('xmax').text = xmax
            bb.find('ymax').text = ymax
            
		# 有多个标签需要添加object
        else:
            label = arr[4, i]
            ymin = arr[0, i]
            ymax = str(int(arr[0, i]) + int(arr[1, i]))
            xmin = arr[2, i]
            xmax = str(int(arr[2, i]) + int(arr[3, i]))


            obj_ori = root.find('object')

            obj = copy.deepcopy(obj_ori)  # 注意这里深拷贝

            obj.find('name').text = label
            bb = obj.find('bndbox')
            bb.find('xmin').text = xmin
            bb.find('ymin').text = ymin
            bb.find('xmax').text = xmax
            bb.find('ymax').text = ymax
            root.append(obj)
            
    xml_file = file_name.replace('png', 'xml')
    tree.write(target_dir + xml_file, encoding='utf-8')    

  希望我的文章对您有所帮助,同时也感谢您能抽出宝贵的时间阅读,如果您喜欢的话,欢迎点赞、关注、收藏。您的支持是我创作的动力,希望今后能带给大家更多优质的文章

你可能感兴趣的:(计算机视觉,python)