,,,,,,,<_python ner 标注 格式 转换">搜索查看编辑修改首页UNITYNODEJSPYTHONAIGITPHPGOCEF3JAVAHTMLCSS搜索Gausst松鼠会 这个屌丝很懒,什么也没留下! 关注作者热门标签jqueryHTMLCSSPHPASPPYTHONGOAICC++C#PHOTOSHOPUNITYiOSandroidvuexml爬虫SEOLINUXWINDOWSJAVAMFCCEF3CADNODEJSGITPyppeteerarticle热门文章1Modelsim do文件的自动化仿真及模板_modelsim 切换 到 目录 do 文件 仿真 vlib work vlib work2Java还是要系统学习,阿里面试失败的经验总结,最终获字节offer_阿里一面答得不好3AIGC 与游戏的深度融合:腾讯全链路解决方案42023年 HCIP-Datacom(H12-831)最新题库_hcip-datacom题库5天星数科以金融数字化转型为核心,提升服务实体经济质效6在Linux系统下检测U盘是否已连接的方法_linux系统查看u盘识别到没有7预测房价--基于python的线性回归模型_房价预测模型python8数据集说明文档_nus_48e9Centos离线手动安装gcc_gcc_rpm.tar.gz10使用 Verilog HDL 在 FPGA 上进行图像处理_去图像坏点 verilog当前位置: article > 正文 自学python(3):python处理各种标注文件的格式转换(json,txt,xml相互转化)_python ner 标注 格式 转换 作者:Gausst松鼠会 | 2024-04-02 10:04:55 赞踩python ner 标注 格式 转换 目录 #txt转xml #xml转txt #json转xml #xml转json #txt转xml # coding: utf-8# author: HXY# 2020-4-17 """该脚本用于visdrone数据处理;将annatations文件夹中的txt标签文件转换为XML文件;txt标签内容为:<bbox_left>,<bbox_top>,<bbox_width>,<bbox_height>,<score>,<object_category>,<truncation>,<occlusion>类别:ignored regions(0), pedestrian(1),people(2), bicycle(3), car(4), van(5),truck(6), tricycle(7), awning-tricycle(8),bus(9), motor(10), others(11)""" import osimport cv2import timefrom xml.dom import minidom name_dict = {'0': 'ignored regions', '1': 'pedestrian', '2': 'people', '3': 'bicycle', '4': 'car', '5': 'van', '6': 'truck', '7': 'tricycle', '8': 'awning-tricycle', '9': 'bus', '10': 'motor', '11': 'others'} def transfer_to_xml(pic, txt, file_name): xml_save_path = 'F:/bling/data/VisDrone2019-DET-train/Annotations_XML' # 生成的xml文件存储的文件夹 if not os.path.exists(xml_save_path): os.mkdir(xml_save_path) img = cv2.imread(pic) img_w = img.shape[1] img_h = img.shape[0] img_d = img.shape[2] doc = minidom.Document() annotation = doc.createElement("annotation") doc.appendChild(annotation) folder = doc.createElement('folder') folder.appendChild(doc.createTextNode('visdrone')) annotation.appendChild(folder) filename = doc.createElement('filename') filename.appendChild(doc.createTextNode(file_name)) annotation.appendChild(filename) source = doc.createElement('source') database = doc.createElement('database') database.appendChild(doc.createTextNode("Unknown")) source.appendChild(database) annotation.appendChild(source) size = doc.createElement('size') width = doc.createElement('width') width.appendChild(doc.createTextNode(str(img_w))) size.appendChild(width) height = doc.createElement('height') height.appendChild(doc.createTextNode(str(img_h))) size.appendChild(height) depth = doc.createElement('depth') depth.appendChild(doc.createTextNode(str(img_d))) size.appendChild(depth) annotation.appendChild(size) segmented = doc.createElement('segmented') segmented.appendChild(doc.createTextNode("0")) annotation.appendChild(segmented) with open(txt, 'r') as f: lines = [f.readlines()] for line in lines: for boxes in line: box = boxes.strip('/n') box = box.split(',') x_min = box[0] y_min = box[1] x_max = int(box[0]) + int(box[2]) y_max = int(box[1]) + int(box[3]) object_name = name_dict[box[5]] # if object_name is 'ignored regions' or 'others': # continue object = doc.createElement('object') nm = doc.createElement('name') nm.appendChild(doc.createTextNode(object_name)) object.appendChild(nm) pose = doc.createElement('pose') pose.appendChild(doc.createTextNode("Unspecified")) object.appendChild(pose) truncated = doc.createElement('truncated') truncated.appendChild(doc.createTextNode("1")) object.appendChild(truncated) difficult = doc.createElement('difficult') difficult.appendChild(doc.createTextNode("0")) object.appendChild(difficult) bndbox = doc.createElement('bndbox') xmin = doc.createElement('xmin') xmin.appendChild(doc.createTextNode(x_min)) bndbox.appendChild(xmin) ymin = doc.createElement('ymin') ymin.appendChild(doc.createTextNode(y_min)) bndbox.appendChild(ymin) xmax = doc.createElement('xmax') xmax.appendChild(doc.createTextNode(str(x_max))) bndbox.appendChild(xmax) ymax = doc.createElement('ymax') ymax.appendChild(doc.createTextNode(str(y_max))) bndbox.appendChild(ymax) object.appendChild(bndbox) annotation.appendChild(object) with open(os.path.join(xml_save_path, file_name + '.xml'), 'w') as x: x.write(doc.toprettyxml()) x.close() f.close() if __name__ == '__main__': t = time.time() print('Transfer .txt to .xml...ing....') txt_folder = 'F:/bling/data/VisDrone2019-DET-train/annotations' # visdrone txt标签文件夹 txt_file = os.listdir(txt_folder) img_folder = 'F:/bling/data/VisDrone2019-DET-train/images' # visdrone 照片所在文件夹 for txt in txt_file: txt_full_path = os.path.join(txt_folder, txt) img_full_path = os.path.join(img_folder, txt.split('.')[0] + '.jpg') try: transfer_to_xml(img_full_path, txt_full_path, txt.split('.')[0]) except Exception as e: print(e) print("Transfer .txt to .XML sucessed. costed: {:.3f}s...".format(time.time() - t)) #xml转txt import osimport xml.etree.ElementTree as ET dirpath = 'F:/bling/data/xml/' #原来存放xml文件的目录newdir = 'F:/bling/data/txt/' #修改label后形成的txt目录 if not os.path.exists(newdir): os.makedirs(newdir) for fp in os.listdir(dirpath): root = ET.parse(os.path.join(dirpath,fp)).getroot() xmin, ymin, xmax, ymax = 0,0,0,0 sz = root.find('size') width = float(sz[0].text) height = float(sz[1].text) filename = root.find('filename').text for child in root.findall('object'): #找到图片中的所有框 #print(child.find('name').text) sub = child.find('bndbox') #找到框的标注值并进行读取 label = child.find('name').text xmin = float(sub[0].text) ymin = float(sub[1].text) xmax = float(sub[2].text) ymax = float(sub[3].text) try: #转换成yolov3的标签格式,需要归一化到(0-1)的范围内 x_center = (xmin + xmax) / (2 * width) y_center = (ymin + ymax) / (2 * height) w = (xmax - xmin) / width h = (ymax - ymin) / height except ZeroDivisionError: print(filename,'的 width有问题') with open(os.path.join(newdir, fp.split('.')[0]+'.txt'), 'a+') as f: f.write(' '.join([str(label), str(x_center), str(y_center), str(w), str(h) + '\n'])) print('ok') #json转xml import xmltodictimport jsonimport os# json to xmldef jsonToXml(json_str): try: xml_str="" xml_str = xmltodict.unparse(json_str, encoding='utf-8') except: xml_str = xmltodict.unparse({'request': json_str}, encoding='utf-8') finally: return xml_str def json_to_xml(json_path,xml_path): if(os.path.exists(xml_path)==False): os.makedirs(xml_path) dir = os.listdir(json_path) for file in dir: file_list=file.split(".") with open(os.path.join(json_path,file), 'r') as load_f: load_dict = json.load(load_f) json_result = jsonToXml(load_dict) f = open(os.path.join(xml_path,file_list[0]+".xml"), 'w', encoding="UTF-8") f.write(json_result) f.close()if __name__ == '__main__': json_path=r"F:/bling/data/json" #该目录为存放json文件的路径 ps:目录中只能存放json文件 xml_path=r"F:/bling/data/train" #该目录为放xml文件的路径 json_to_xml(json_path,xml_path) #xml转json import cv2import xml.etree.ElementTree as ET import numpy as npimport osimport jsonimport shutilimport base64'''该脚本实现将xml类型标签(或者yolo格式标签)转为json格式标签需要的数据:原始图像 原始xml标签(原始txt标签)''' # 解析数据集,输入单张图片路径,图片路径不能出现中文,因为是cv2读取的。和对应xml文件的路径# 返回图片 该图所有的目标框[[x1,y1,x2,y2],....] 每个框的类别[label1, label2, label3,.....] 注意是label而不是索引def parse_img_label(img_path, xml_path): # 绝对路径 img = cv2.imread(img_path) tree = ET.parse(xml_path) root = tree.getroot() objs = root.findall('object') bboxes = [] # 坐标框 h ,w = img.shape[0], img.shape[1] #gt_labels = [] # 标签名 for obj in objs: # 遍历所有的目标 label = obj[0].text # <name>这个tag的值,即标签 label = label.strip(' ') box = [int(obj[4][i].text) for i in range(4)] box.append(label) # box的元素 x1 y1 x2 y2 类别 bboxes.append(box) return img, bboxes # 该函数用于将yolo的标签转回xml需要的标签。。即将归一化后的坐标转为原始的像素坐标def convert_yolo_xml(box,img): # x,y,w,h = box[0], box[1], box[2], box[3] # 求出原始的x1 x2 y1 y2 x2 = (2*x + w)*img.shape[1] /2 x1 = x2 - w*img.shape[1] y2 = (2*y+h)*img.shape[0] /2 y1 = y2 - h* img.shape[0] new_box = [x1,y1, x2, y2] new_box = list(map(int,new_box)) return new_box # 该函数用于解析yolo格式的数据集,即txt格式的标注 返回图像 边框坐标 真实标签名(不是索引,因此需要预先定义标签)def parse_img_txt(img_path, txt_path): name_label = ['class0','class1','class2'] # 需要自己预先定义,它的顺序要和实际yolo格式的标签中0 1 2 3的标签对应 yolo标签的类别是索引 而不是名字 img = cv2.imread(img_path) f = open(txt_path) bboxes = [] for line in f.readlines(): line = line.split(" ") if len(line) == 5: obj_label = name_label[int(line[0])] # 将类别索引转成其名字 x = float(line[1]) y = float(line[2]) w = float(line[3]) h = float(line[4]) box = convert_yolo_xml([x,y,w,h], img) box.append(obj_label) bboxes.append(box) return img, bboxes # 制作labelme格式的标签# 参数说明 img_name: 图像文件名称 # txt_name: 标签文件的绝对路径,注意是绝对路径# prefix: 图像文件的上级目录名。即形如/home/xjzh/data/ 而img_name是其下的文件名,如00001.jpg# prefix+img_name即为图像的绝对路径。不该路径能出现中文,否则cv2读取会有问题# def get_json(img_name, txt_name, prefix, yolo=False): # 图片名 标签名 前缀 label_dict = {} # json字典,依次填充它的value label_dict["imagePath"] = prefix + img_name # 图片路径 label_dict["fillColor"] = [255,0,0,128] # 目标区域的填充颜色 RGBA label_dict["lineColor"] = [0,255,0,128] # 线条颜色 label_dict["flag"] = {} label_dict["version"] = "3.16.7" # 版本号,随便 with open(prefix + img_name,"rb") as f: img_data = f.read() base64_data = base64.b64encode(img_data) base64_str = str(base64_data, 'utf-8') label_dict["imageData"] = base64_str # labelme的json文件存放了图像的base64编码。这样如果图像路径有问题仍然能够打开文件 img, gt_box = parse_img_label(prefix + img_name, txt_name) if not yolo else parse_img_txt(prefix + img_name, txt_name) # 读取真实数据 label_dict["imageHeight"] = img.shape[0] # 高度 label_dict["imageWidth"] = img.shape[1] shape_list = [] # 存放标注信息的列表,它是 shapes这个键的值。里面是一个列表,每个元素又是一个字典,字典内容是该标注的类型 颜色 坐标点等等 #label_dict["shapes"] = [] # 列表,每个元素是字典。 # box的元素 x1 y1 x2 y2 类别 for box in gt_box: shape_dict = {} # 表示一个目标的字典 shape_dict["shape_type"] = "rectangle" # 因为xml或yolo格式标签是矩形框标注,因此是rectangle shape_dict["fill_color"] = None #该类型的填充颜色 shape_dict["line_color"] = None # 线条颜色 可以设置,或者根据标签名自己预先设定labe_color_dict shape_dict["flags"] = {} shape_dict["label"] = box[-1] # 标签名 shape_dict["points"] = [[box[0],box[1]], [box[2], box[3]]] # 通常contours是长度为1的列表,如果有分块,可能就有多个 # [[x1,y1], [x2,y2]...]的列表 shape_list.append(shape_dict) label_dict["shapes"] = shape_list # return label_dict imgs_path = "F:/bling/data/images/" # 图像路径xmls_path ="F:/bling/data/xml/" # xml文件路径 img_path = os.listdir(imgs_path)out_json = 'F:/bling/data/json/' # 保存的json文件路径 for nums, path in enumerate(img_path): if nums %200==0: print(f"processed {nums} images") xml_path = xmls_path + path.replace('jpg','xml') # xml文件的绝对路径 label_dict = get_json(path, xml_path,prefix=imgs_path) # with open(out_json + path.replace("jpg","json"),'w') as f: # 写入一个json文件 f.write(json.dumps(label_dict, ensure_ascii=False, indent=4, separators=(',', ':'))) 声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】推荐阅读article「Python」pycharm多项目虚拟环境切换_pycharm terminal切换到另外项目...背景pycharm打开了多个项目,如图:每个项目带不同的虚拟环境,如果直接从pycharm底部的Terminal打开终端... 赞踩articlePycharm中用run with Python console调试脚本...Pycharm run with Python console有时,需要在Pycharm下像IDLE那样做一些shell... 赞踩articlecv2.error: OpenCV(4.9.0) D:\a\opencv-python\opencv...ddddocr_cv2.error: opencv(4.9.0) d:\a\opencv-python\opencv-p... 赞踩articlecv2.error: OpenCV(4.8.0) D:\a\opencv-python\opencv...解决方法:卸载opencv-python 和 opencv-contrib-python。重新安装opencv-pyth... 赞踩article一万六千字大章:Chrome 浏览器插件 V3 版本 Manifest.json 文件全字段解析_c...Chrome 浏览器插件 V3 版本 Manifest.json 文件全字段解析,一万六千字大章全字段图文解析_chro... 赞踩articlepython 基于情感词典的情感分析之乐,惧,惊,哀,恶,怒和未知七种情感分析_知网情感词典的pyt...背景情感分析是通过计算技术对文本内容的主观客观性、情绪等挖掘分析,对文本的情感偏向做出判断。目的是识别出文本中的具体情感... 赞踩articleblender python API 编程让3D建模插上双翼腾飞_blender python建模...通过这种功能,我们遇到不知道怎么写python代码的时候,可以先在blender里通过传统的手动方式操作一遍,然后将生成... 赞踩articlePython 与 Blender_blender python...Python 与 Blender前言安装 Blender简单了解 Blender配置 BlenderBlender 的快... 赞踩articleBlender之python命令api调用交互_blender python api...本文是如何在blender中使用Python代码执行命令交互,算是一个新手教程,包含如何通过Python命令新建物体,以... 赞踩articleBlender程序化设置材质【Python】_blender scripts shader...本文介绍如何使用Python创建新材质、添加着色器、创建新对象并将材质分配给Blender中的对象。然后为材质添加着色器... 赞踩articleJSON parse error: Illegal unquoted character ((CTR...JSON解析错误:非法的无引号字符((CTRL-CHAR,代码10):必须使用反斜杠进行转义才能包含在字符串值中;嵌套异... 赞踩article华为OD机试 - 最大坐标值、小明的幸运数(Java & JS & Python & C & C++...小明在玩一个游戏,游戏规则如下:在游戏开始前,小明站在坐标轴原点处(坐标值为0).给定一组指令和一个幸运数,每个指令都是... 赞踩articlePython 经典算法100及解析(小结)_money = int(input('净利润:')) a...1:找出字符串s="aaabbbccceeefff111144444"中,字符出现次数最多的字符(1)考虑去重,首先将字... 赞踩articlePython 机器人学 —— 机械臂工作空间分析...设关节1、关节5的高 (圆柱高) 分别为,5个关节的转动角分别为2 - 33 - 44 - **- 55 - H因为把各... 赞踩articlepython 建筑计算_用相关系数从真实建筑数据中挖掘影响建筑能耗的因素...前言:传统的建筑能耗分析来源于建筑的物理模型,主要是基于传热学理论发展而来,这种方法也常被称为“白箱模型”。如果从传热角... 赞踩articlePython 数据分析微专业课程--项目实战09 房价影响因素挖掘1.项目说明2.项目具体要求3.实...1.项目说明分析上海房价和房租,计算租售比;分析上海市人口密度、路网密度、餐饮价格和房价的关系。2.项目具体要求1、数据... 赞踩articlePython 数据分析微专业课程--项目实战09 房价影响因素挖掘_python房价影响因素挖掘...1.项目说明分析上海房价和房租,计算租售比;分析上海市人口密度、路网密度、餐饮价格和房价的关系。2.项目具体要求1、数据... 赞踩articlepython-sklearn岭回归与LASSO回归模型(套索)代码实操_lasso代码...学习岭回归与LASSO回归模型的sklearn实现。岭回归:平方和(L2正则化);LASSO回归:绝对值(L1正则化)。... 赞踩articlePython 数据分析微专业课程--项目实战12 财富分配实验_富值每天减少千分之二,365天后财富...1.项目说明 构建财富分配模型,模拟不允许借贷情况下的财富分配,允许借贷下的财富分配,努力型人生的财富分配2.项目具体要... 赞踩articlePython 数据分析微专业课程--项目07 电商打折套路解析_python数据分析电商打折分析课...1.项目说明基于双十一淘宝美妆数据分析双十一期间各品牌化妆品的销售情况及打折情况,并分析个品牌化妆品的打折特点,分析其套... 赞踩相关标签pycharmpythonideopencvjavascript人工智能chrome前端Manifest.jsonManifest V3chrome 插件浏览器浏览器插件blender材质jsonspring bootjavamaven华为od
赞
踩
目录
#txt转xml
#xml转txt
#json转xml
#xml转json
# coding: utf-8# author: HXY# 2020-4-17 """该脚本用于visdrone数据处理;将annatations文件夹中的txt标签文件转换为XML文件;txt标签内容为:<bbox_left>,<bbox_top>,<bbox_width>,<bbox_height>,<score>,<object_category>,<truncation>,<occlusion>类别:ignored regions(0), pedestrian(1),people(2), bicycle(3), car(4), van(5),truck(6), tricycle(7), awning-tricycle(8),bus(9), motor(10), others(11)""" import osimport cv2import timefrom xml.dom import minidom name_dict = {'0': 'ignored regions', '1': 'pedestrian', '2': 'people', '3': 'bicycle', '4': 'car', '5': 'van', '6': 'truck', '7': 'tricycle', '8': 'awning-tricycle', '9': 'bus', '10': 'motor', '11': 'others'} def transfer_to_xml(pic, txt, file_name): xml_save_path = 'F:/bling/data/VisDrone2019-DET-train/Annotations_XML' # 生成的xml文件存储的文件夹 if not os.path.exists(xml_save_path): os.mkdir(xml_save_path) img = cv2.imread(pic) img_w = img.shape[1] img_h = img.shape[0] img_d = img.shape[2] doc = minidom.Document() annotation = doc.createElement("annotation") doc.appendChild(annotation) folder = doc.createElement('folder') folder.appendChild(doc.createTextNode('visdrone')) annotation.appendChild(folder) filename = doc.createElement('filename') filename.appendChild(doc.createTextNode(file_name)) annotation.appendChild(filename) source = doc.createElement('source') database = doc.createElement('database') database.appendChild(doc.createTextNode("Unknown")) source.appendChild(database) annotation.appendChild(source) size = doc.createElement('size') width = doc.createElement('width') width.appendChild(doc.createTextNode(str(img_w))) size.appendChild(width) height = doc.createElement('height') height.appendChild(doc.createTextNode(str(img_h))) size.appendChild(height) depth = doc.createElement('depth') depth.appendChild(doc.createTextNode(str(img_d))) size.appendChild(depth) annotation.appendChild(size) segmented = doc.createElement('segmented') segmented.appendChild(doc.createTextNode("0")) annotation.appendChild(segmented) with open(txt, 'r') as f: lines = [f.readlines()] for line in lines: for boxes in line: box = boxes.strip('/n') box = box.split(',') x_min = box[0] y_min = box[1] x_max = int(box[0]) + int(box[2]) y_max = int(box[1]) + int(box[3]) object_name = name_dict[box[5]] # if object_name is 'ignored regions' or 'others': # continue object = doc.createElement('object') nm = doc.createElement('name') nm.appendChild(doc.createTextNode(object_name)) object.appendChild(nm) pose = doc.createElement('pose') pose.appendChild(doc.createTextNode("Unspecified")) object.appendChild(pose) truncated = doc.createElement('truncated') truncated.appendChild(doc.createTextNode("1")) object.appendChild(truncated) difficult = doc.createElement('difficult') difficult.appendChild(doc.createTextNode("0")) object.appendChild(difficult) bndbox = doc.createElement('bndbox') xmin = doc.createElement('xmin') xmin.appendChild(doc.createTextNode(x_min)) bndbox.appendChild(xmin) ymin = doc.createElement('ymin') ymin.appendChild(doc.createTextNode(y_min)) bndbox.appendChild(ymin) xmax = doc.createElement('xmax') xmax.appendChild(doc.createTextNode(str(x_max))) bndbox.appendChild(xmax) ymax = doc.createElement('ymax') ymax.appendChild(doc.createTextNode(str(y_max))) bndbox.appendChild(ymax) object.appendChild(bndbox) annotation.appendChild(object) with open(os.path.join(xml_save_path, file_name + '.xml'), 'w') as x: x.write(doc.toprettyxml()) x.close() f.close() if __name__ == '__main__': t = time.time() print('Transfer .txt to .xml...ing....') txt_folder = 'F:/bling/data/VisDrone2019-DET-train/annotations' # visdrone txt标签文件夹 txt_file = os.listdir(txt_folder) img_folder = 'F:/bling/data/VisDrone2019-DET-train/images' # visdrone 照片所在文件夹 for txt in txt_file: txt_full_path = os.path.join(txt_folder, txt) img_full_path = os.path.join(img_folder, txt.split('.')[0] + '.jpg') try: transfer_to_xml(img_full_path, txt_full_path, txt.split('.')[0]) except Exception as e: print(e) print("Transfer .txt to .XML sucessed. costed: {:.3f}s...".format(time.time() - t))
import osimport xml.etree.ElementTree as ET dirpath = 'F:/bling/data/xml/' #原来存放xml文件的目录newdir = 'F:/bling/data/txt/' #修改label后形成的txt目录 if not os.path.exists(newdir): os.makedirs(newdir) for fp in os.listdir(dirpath): root = ET.parse(os.path.join(dirpath,fp)).getroot() xmin, ymin, xmax, ymax = 0,0,0,0 sz = root.find('size') width = float(sz[0].text) height = float(sz[1].text) filename = root.find('filename').text for child in root.findall('object'): #找到图片中的所有框 #print(child.find('name').text) sub = child.find('bndbox') #找到框的标注值并进行读取 label = child.find('name').text xmin = float(sub[0].text) ymin = float(sub[1].text) xmax = float(sub[2].text) ymax = float(sub[3].text) try: #转换成yolov3的标签格式,需要归一化到(0-1)的范围内 x_center = (xmin + xmax) / (2 * width) y_center = (ymin + ymax) / (2 * height) w = (xmax - xmin) / width h = (ymax - ymin) / height except ZeroDivisionError: print(filename,'的 width有问题') with open(os.path.join(newdir, fp.split('.')[0]+'.txt'), 'a+') as f: f.write(' '.join([str(label), str(x_center), str(y_center), str(w), str(h) + '\n'])) print('ok')
import xmltodictimport jsonimport os# json to xmldef jsonToXml(json_str): try: xml_str="" xml_str = xmltodict.unparse(json_str, encoding='utf-8') except: xml_str = xmltodict.unparse({'request': json_str}, encoding='utf-8') finally: return xml_str def json_to_xml(json_path,xml_path): if(os.path.exists(xml_path)==False): os.makedirs(xml_path) dir = os.listdir(json_path) for file in dir: file_list=file.split(".") with open(os.path.join(json_path,file), 'r') as load_f: load_dict = json.load(load_f) json_result = jsonToXml(load_dict) f = open(os.path.join(xml_path,file_list[0]+".xml"), 'w', encoding="UTF-8") f.write(json_result) f.close()if __name__ == '__main__': json_path=r"F:/bling/data/json" #该目录为存放json文件的路径 ps:目录中只能存放json文件 xml_path=r"F:/bling/data/train" #该目录为放xml文件的路径 json_to_xml(json_path,xml_path)
import cv2import xml.etree.ElementTree as ET import numpy as npimport osimport jsonimport shutilimport base64'''该脚本实现将xml类型标签(或者yolo格式标签)转为json格式标签需要的数据:原始图像 原始xml标签(原始txt标签)''' # 解析数据集,输入单张图片路径,图片路径不能出现中文,因为是cv2读取的。和对应xml文件的路径# 返回图片 该图所有的目标框[[x1,y1,x2,y2],....] 每个框的类别[label1, label2, label3,.....] 注意是label而不是索引def parse_img_label(img_path, xml_path): # 绝对路径 img = cv2.imread(img_path) tree = ET.parse(xml_path) root = tree.getroot() objs = root.findall('object') bboxes = [] # 坐标框 h ,w = img.shape[0], img.shape[1] #gt_labels = [] # 标签名 for obj in objs: # 遍历所有的目标 label = obj[0].text # <name>这个tag的值,即标签 label = label.strip(' ') box = [int(obj[4][i].text) for i in range(4)] box.append(label) # box的元素 x1 y1 x2 y2 类别 bboxes.append(box) return img, bboxes # 该函数用于将yolo的标签转回xml需要的标签。。即将归一化后的坐标转为原始的像素坐标def convert_yolo_xml(box,img): # x,y,w,h = box[0], box[1], box[2], box[3] # 求出原始的x1 x2 y1 y2 x2 = (2*x + w)*img.shape[1] /2 x1 = x2 - w*img.shape[1] y2 = (2*y+h)*img.shape[0] /2 y1 = y2 - h* img.shape[0] new_box = [x1,y1, x2, y2] new_box = list(map(int,new_box)) return new_box # 该函数用于解析yolo格式的数据集,即txt格式的标注 返回图像 边框坐标 真实标签名(不是索引,因此需要预先定义标签)def parse_img_txt(img_path, txt_path): name_label = ['class0','class1','class2'] # 需要自己预先定义,它的顺序要和实际yolo格式的标签中0 1 2 3的标签对应 yolo标签的类别是索引 而不是名字 img = cv2.imread(img_path) f = open(txt_path) bboxes = [] for line in f.readlines(): line = line.split(" ") if len(line) == 5: obj_label = name_label[int(line[0])] # 将类别索引转成其名字 x = float(line[1]) y = float(line[2]) w = float(line[3]) h = float(line[4]) box = convert_yolo_xml([x,y,w,h], img) box.append(obj_label) bboxes.append(box) return img, bboxes # 制作labelme格式的标签# 参数说明 img_name: 图像文件名称 # txt_name: 标签文件的绝对路径,注意是绝对路径# prefix: 图像文件的上级目录名。即形如/home/xjzh/data/ 而img_name是其下的文件名,如00001.jpg# prefix+img_name即为图像的绝对路径。不该路径能出现中文,否则cv2读取会有问题# def get_json(img_name, txt_name, prefix, yolo=False): # 图片名 标签名 前缀 label_dict = {} # json字典,依次填充它的value label_dict["imagePath"] = prefix + img_name # 图片路径 label_dict["fillColor"] = [255,0,0,128] # 目标区域的填充颜色 RGBA label_dict["lineColor"] = [0,255,0,128] # 线条颜色 label_dict["flag"] = {} label_dict["version"] = "3.16.7" # 版本号,随便 with open(prefix + img_name,"rb") as f: img_data = f.read() base64_data = base64.b64encode(img_data) base64_str = str(base64_data, 'utf-8') label_dict["imageData"] = base64_str # labelme的json文件存放了图像的base64编码。这样如果图像路径有问题仍然能够打开文件 img, gt_box = parse_img_label(prefix + img_name, txt_name) if not yolo else parse_img_txt(prefix + img_name, txt_name) # 读取真实数据 label_dict["imageHeight"] = img.shape[0] # 高度 label_dict["imageWidth"] = img.shape[1] shape_list = [] # 存放标注信息的列表,它是 shapes这个键的值。里面是一个列表,每个元素又是一个字典,字典内容是该标注的类型 颜色 坐标点等等 #label_dict["shapes"] = [] # 列表,每个元素是字典。 # box的元素 x1 y1 x2 y2 类别 for box in gt_box: shape_dict = {} # 表示一个目标的字典 shape_dict["shape_type"] = "rectangle" # 因为xml或yolo格式标签是矩形框标注,因此是rectangle shape_dict["fill_color"] = None #该类型的填充颜色 shape_dict["line_color"] = None # 线条颜色 可以设置,或者根据标签名自己预先设定labe_color_dict shape_dict["flags"] = {} shape_dict["label"] = box[-1] # 标签名 shape_dict["points"] = [[box[0],box[1]], [box[2], box[3]]] # 通常contours是长度为1的列表,如果有分块,可能就有多个 # [[x1,y1], [x2,y2]...]的列表 shape_list.append(shape_dict) label_dict["shapes"] = shape_list # return label_dict imgs_path = "F:/bling/data/images/" # 图像路径xmls_path ="F:/bling/data/xml/" # xml文件路径 img_path = os.listdir(imgs_path)out_json = 'F:/bling/data/json/' # 保存的json文件路径 for nums, path in enumerate(img_path): if nums %200==0: print(f"processed {nums} images") xml_path = xmls_path + path.replace('jpg','xml') # xml文件的绝对路径 label_dict = get_json(path, xml_path,prefix=imgs_path) # with open(out_json + path.replace("jpg","json"),'w') as f: # 写入一个json文件 f.write(json.dumps(label_dict, ensure_ascii=False, indent=4, separators=(',', ':')))