最近在做yolo检测,解决了一个困扰了我很久的难题,因为我的数据集大部分是使用labelme人体关键点json标注格式,就是如何将人体关键点数据集json标注格式转换成xml格式。
Json格式:
只需将json的 "shapes" 字段解析出来即可,具体代码实现如下
import argparse
import json
import os
import cv2
import glob
import xml.etree.ElementTree as ET
from xml.dom import minidom
def bbox2voc(imgPath, xmlDir, bboxes):
annotation = ET.Element("annotation")
imSrc = cv2.imread(imgPath)
imgDir, imgName = os.path.split(imgPath)
try:
h, w, c = imSrc.shape
except:
# print(image_path, "is not exit!")
return
ET.SubElement(annotation, "filename", ).text = imgName
image_size = ET.SubElement(annotation, 'size')
ET.SubElement(image_size, 'width').text = str(w)
ET.SubElement(image_size, 'height').text = str(h)
ET.SubElement(image_size, 'depth').text = str(3)
for box in bboxes:
object = ET.SubElement(annotation, "object")
ET.SubElement(object, 'name').text = str(box[4])
ET.SubElement(object, 'difficult').text = str(0)
bndbox = ET.SubElement(object, "bndbox")
ET.SubElement(bndbox, 'xmin').text = str(box[0])
ET.SubElement(bndbox, 'ymin').text = str(box[1])
ET.SubElement(bndbox, 'xmax').text = str(box[2])
ET.SubElement(bndbox, 'ymax').text = str(box[3])
xmlstr = minidom.parseString(ET.tostring(annotation)).toprettyxml(indent=" ")
xmlPath = imgPath.replace('.jpg', '.xml').replace(imgDir, xmlDir)
with open(xmlPath, "w", encoding='utf-8') as f:
f.write(xmlstr)
def pose2bboxes(imgJsonPath, xmlDir):
print('dir {}'.format(imgJsonPath))
labelMeJsons = glob.glob(os.path.join(imgJsonPath, '*.json'))
for labelMeJson in labelMeJsons:
imgPath = labelMeJson.replace('.json', '.jpg')
bboxes = []
with open(labelMeJson, 'r') as labelMeJsonF:
jsonDataLabelMe = json.load(labelMeJsonF)
for labelMeshape in jsonDataLabelMe['shapes']:
if 'rectangle' == labelMeshape['shape_type']:
x0, y0, x1, y1 = labelMeshape['points'][0][0], labelMeshape['points'][0][1], labelMeshape['points'][1][0], labelMeshape['points'][1][1],
xmin = max(min(x0, x1), 0)
ymin = max(min(y0, y1), 0)
xmax = max(x0, x1)
ymax = max(y0, y1)
bbox = [xmin, ymin, xmax, ymax]
bboxes.append([int(bbox[0]), int(bbox[1]), int(bbox[2]), int(bbox[3]), labelMeshape['label']])
bbox2voc(imgPath, xmlDir, bboxes)
if __name__ == '__main__':
imgJsonPath = r'G:\XrwProject\selfjson01'
xmlDir = (imgJsonPath + 'Xml').replace('/04', '/06')
os.makedirs(xmlDir, exist_ok=True)
pose2bboxes(imgJsonPath, xmlDir)
imgJsonPath:为json存放的路径
运行代码,会在json路径同级创建一个文件夹,将xml存放进去
生成的xml格式:
打开labelimg、验证是否转换成功