> 文章列表 > 数据格式转换(labelme、labelimg、yolo格式相互转换)

数据格式转换(labelme、labelimg、yolo格式相互转换)

数据格式转换(labelme、labelimg、yolo格式相互转换)

👨‍💻个人简介: 深度学习图像领域工作者
🎉总结链接:
             链接中主要是个人工作的总结,每个链接都是一些常用demo,代码直接复制运行即可。包括:
                    📌1.工作中常用深度学习脚本
                    📌2.torch、numpy等常用函数详解
                    📌3.opencv 图片、视频等操作
                    📌4.个人工作中的项目总结(纯干活)
              链接: https://blog.csdn.net/qq_28949847/article/details/128552785
🎉视频讲解: 以上记录,通过B站等平台进行了视频讲解使用,可搜索 ‘Python图像识别’ 进行观看
              B站:Python图像识别
              抖音:Python图像识别
              西瓜视频:Python图像识别


目录

  • 1. 目标检测矩形框转换
    • (1)labelme标注的数据json文件转为labelimg格式的xml文件
    • (2)labelimg xml文件转 labelme json文件

1. 目标检测矩形框转换

(1)labelme标注的数据json文件转为labelimg格式的xml文件

目前只能支持 json中 ‘rectangle’ 和 ‘polygon’ 两种模式的转换,其中 ‘polygon’ 的转换方式为,替换成最小外接矩形的左上角和右下角坐标

输入:由labelme的rectangle或这polygon方式标注生成的json文件;

输出:类似于labelImg的rectangle方式标注生成的xml文件,是左上角和右下角的坐标。

个人只需修改相应的路径。

# -*- coding: utf-8 -*-
import numpy as np
import json
from lxml import etree
import os
from tqdm import tqdmclass ReadJson(object):'''读取json文件,获取相应的标签信息'''def __init__(self, json_path):self.json_data = json.load(open(json_path, encoding="utf-8"))self.filename = self.json_data['imagePath']self.width = self.json_data['imageWidth']self.height = self.json_data['imageHeight']self.coordis = []# 构建坐标self.process_shapes()def process_shapes(self):for single_shape in self.json_data['shapes']:if single_shape['shape_type'] == "rectangle":bbox_class = single_shape['label']xmin = single_shape['points'][0][0]ymin = single_shape['points'][0][1]xmax = single_shape['points'][1][0]ymax = single_shape['points'][1][1]self.coordis.append([xmin, ymin, xmax, ymax, bbox_class])elif single_shape['shape_type'] == 'polygon':bbox_class = single_shape['label']temp_points = single_shape['points']temp_points = np.array(temp_points)xmin, ymin = temp_points.min(axis=0)xmax, ymax = temp_points.max(axis=0)self.coordis.append([xmin, ymin, xmax, ymax, bbox_class])else:print("shape type error, shape_type not in ['rectangle', 'polygon']")def get_width_height(self):return self.width, self.heightdef get_filename(self):return self.filenamedef get_coordis(self):return self.coordisclass labelimg_Annotations_xml:def __init__(self, folder_name, filename, path, database="Unknown"):self.root = etree.Element("annotation")child1 = etree.SubElement(self.root, "folder")child1.text = folder_namechild2 = etree.SubElement(self.root, "filename")child2.text = filenamechild3 = etree.SubElement(self.root, "path")child3.text = pathchild4 = etree.SubElement(self.root, "source")child5 = etree.SubElement(child4, "database")child5.text = databasedef set_size(self, width, height, channel):size = etree.SubElement(self.root, "size")widthn = etree.SubElement(size, "width")widthn.text = str(width)heightn = etree.SubElement(size, "height")heightn.text = str(height)channeln = etree.SubElement(size, "channel")channeln.text = str(channel)def set_segmented(self, seg_data=0):segmented = etree.SubElement(self.root, "segmented")segmented.text = str(seg_data)def set_object(self, label, x_min, y_min, x_max, y_max,pose='Unspecified', truncated=0, difficult=0):object = etree.SubElement(self.root, "object")namen = etree.SubElement(object, "name")namen.text = labelposen = etree.SubElement(object, "pose")posen.text = posetruncatedn = etree.SubElement(object, "truncated")truncatedn.text = str(truncated)difficultn = etree.SubElement(object, "difficult")difficultn.text = str(difficult)bndbox = etree.SubElement(object, "bndbox")xminn = etree.SubElement(bndbox, "xmin")xminn.text = str(x_min)yminn = etree.SubElement(bndbox, "ymin")yminn.text = str(y_min)xmaxn = etree.SubElement(bndbox, "xmax")xmaxn.text = str(x_max)ymaxn = etree.SubElement(bndbox, "ymax")ymaxn.text = str(y_max)def savefile(self, filename):tree = etree.ElementTree(self.root)tree.write(filename, pretty_print=True, xml_declaration=False, encoding='utf-8')def json_transform_xml(json_path, xml_path):json_anno = ReadJson(json_path)width, height = json_anno.get_width_height()channel = 3filename = json_anno.get_filename()coordis = json_anno.get_coordis()anno = labelimg_Annotations_xml('JPEGImages', filename, 'JPEGImages')anno.set_size(width, height, channel)anno.set_segmented()for data in coordis:x_min, y_min, x_max, y_max, label = dataanno.set_object(label, int(x_min), int(y_min), int(x_max), int(y_max))anno.savefile(xml_path)if __name__ == "__main__":'''目前只能支持 json中 rectangle 和 polygon 两种模式的转换,其中 polygon 的转换方式为,替换成最小外接矩形的左上角和右下角坐标'''root_json_dir = r"C:\\Users\\JoelYang\\Desktop\\111111\\bbox_20230417_gjx"# root_save_xml_dir = r"\\\\SHARE\\public\\Time_Plus\\traindata\\bbox\\tiaoshui3m\\20230418_zxl"root_save_xml_dir = root_json_dirfor json_filename in tqdm(os.listdir(root_json_dir)):if not json_filename.endswith(".json"):continuejson_path = os.path.join(root_json_dir, json_filename)save_xml_path = os.path.join(root_save_xml_dir, json_filename.replace(".json", ".xml"))json_transform_xml(json_path, save_xml_path)

效果如下图:

json文件:
数据格式转换(labelme、labelimg、yolo格式相互转换)

xml文件:
数据格式转换(labelme、labelimg、yolo格式相互转换)

(2)labelimg xml文件转 labelme json文件

import xml.etree.ElementTree as ET
import os
import jsondef xml_transform_json(xml_path, file, save_path):print(os.path.join(xml_path, file))# 读取xml文件path_file_xml = os.path.join(xml_path, file)# 解析读取xml函数root = ET.parse(path_file_xml)folder = root.find('folder').textfilename = root.find('filename').textpath = root.find('path').textsz = root.find('size')width = int(sz[0].text)height = int(sz[1].text)# 构建json数据data = {}data['flags'] = {}data['version'] = "4.5.6"data["shapes"] = []for child in root.findall('object'):  # 找到图片中的所有框sub = child.find('bndbox')  # 找到框的标注值并进行读取xmin = float(sub[0].text)ymin = float(sub[1].text)xmax = float(sub[2].text)ymax = float(sub[3].text)points = [[xmin, ymin], [xmax, ymax]]itemData = {'points': []}itemData['points'].extend(points)name = child.find("name").textitemData["flag"] = {}itemData["group_id"] = NoneitemData["shape_type"] = "rectangle"itemData["label"] = namedata["shapes"].append(itemData)data['imageWidth'] = widthdata['imageHeight'] = heightdata['imageData'] = Nonedata['imagePath'] = filenamefilename, extension = os.path.splitext(file)jsonName = ".".join([filename, "json"])# 写入jsonjson_path = os.path.join(save_path, jsonName)with open(json_path, "w") as f:json.dump(data, f)print(json_path, "加载入文件完成...")if __name__ == '__main__':xml_path = r"C:\\Users\\JoelYang\\Desktop\\111111\\bbox_20230417_gjx"# save_path = r"C:\\Users\\JoelYang\\Desktop\\111111\\bbox_20230417_gjx"save_path = xml_pathfor root, dirs, files in os.walk(xml_path):for file in files:if not file.endswith(".xml"):continuexml_transform_json(root, file, save_path)

效果如下:

xml文件
数据格式转换(labelme、labelimg、yolo格式相互转换)
转后的json文件

数据格式转换(labelme、labelimg、yolo格式相互转换)