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]}}

其中字符的具體座標如下:
在這裏插入圖片描述

注意:這裏與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')    

  希望我的文章對您有所幫助,同時也感謝您能抽出寶貴的時間閱讀,如果您喜歡的話,歡迎點贊、關注、收藏。您的支持是我創作的動力,希望今後能帶給大家更多優質的文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章