json-->txt
import os
import json
import numpy as np
dir_json = r'' #json存储的文件目录
dir_txt = r'' #txt存储目录
if not os.path.exists(dir_txt):
os.makedirs(dir_txt)
list_json = os.listdir(dir_json)
def json2txt(path_json,path_txt): #可修改生成格式
with open(path_json,'r') as path_json:
jsonx=json.load(path_json)
with open(path_txt,'w+') as ftxt:
for shape in jsonx['shapes']:
label = str(shape['label'])+' '
xy=np.array(shape['points'])
strxy = ''
for m,n in xy:
m=int(m)
n=int(n)
strxy+=str(m)+' '+str(n)+' '
label+=strxy
ftxt.writelines(label+"\n")
for cnt,json_name in enumerate(list_json):
print('cnt=%d,name=%s'%(cnt,json_name))
path_json = dir_json + json_name
path_txt = dir_txt + json_name.replace('.json','.txt')
json2txt(path_json,path_txt)
xml-->txt
# -*- coding: utf-8 -*-
import os
import xml.etree.ElementTree as ET
dirpath = r'' # 原来存放xml文件的目录
newdir = r'' # 修改label后形成的txt目录
if not os.path.exists(newdir):
os.makedirs(newdir)
dict_info = {'ripe': 0, 'unripe': 1} # 有几个 属性 填写几个label names
for fp in os.listdir(dirpath):
if fp.endswith('.xml'):
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'): # 找到图片中的所有框
sub = child.find('bndbox') # 找到框的标注值并进行读取
label = child.find('name').text
label_ = dict_info.get(label)
if label_:
label_ = label_
else:
label_ = 0
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)
x_center = '%.6f' % x_center
y_center = (ymin + ymax) / (2 * height)
y_center = '%.6f' % y_center
w = (xmax - xmin) / width
w = '%.6f' % w
h = (ymax - ymin) / height
h = '%.6f' % h
except ZeroDivisionError:
print(filename, '的 width有问题')
with open(os.path.join(newdir, fp.split('.xml')[0] + '.txt'), 'a+') as f:
f.write(' '.join([str(label_), str(x_center), str(y_center), str(w), str(h) + '\n']))
print('ok')
txt-->xml
# -*- coding:UTF-8 -*-
import os
import cv2
def txt_to_xml(classname_path, txt_path, img_path, xml_path):
# 1.读取txt文件中的标签类别
with open(classname_path, 'r') as f:
classes = f.readlines() # list, 每个类别末尾都有'\n'
classes = [cls.strip('\n') for cls in classes]
# 2.找到txt标签文件夹
files = os.listdir(txt_path)
# 用于存储 "老图"
pre_img_name = ''
# 3.遍历文件夹
for i, name in enumerate(files):
# mac系统中文件夹里有该文件,默认的也删不掉,那就直接pass
if name == '.DS_Store':
continue
print(name)
# 4.打开txt
txtFile = open(txt_path + name)
# 读取所有内容
txtList = txtFile.readlines()
# 读取图片名称
img_name = name.split(".")[0]
pic = cv2.imread(img_path + img_name + ".jpg")
# 获取图像大小信息
Pheight, Pwidth, Pdepth = pic.shape
# 5.遍历txt文件中每行内容
for row in txtList:
# 按' '分割txt的一行的内容
oneline = row.strip().split(" ")
# 遇到的是一张新图片
if img_name != pre_img_name:
# 6.新建xml文件
xml_file = open((xml_path + img_name + '.xml'), 'w')
xml_file.write('<annotation>\n')
xml_file.write(' <folder>billiards</folder>\n')
xml_file.write(' <filename>' + img_name + '.jpg' + '</filename>\n')
xml_file.write(' <path>E:/Images</path>\n')
xml_file.write(' <source>\n')
xml_file.write(' <database>orgaquant</database>\n')
xml_file.write(' </source>\n')
xml_file.write(' <size>\n')
xml_file.write(' <width>' + str(Pwidth) + '</width>\n')
xml_file.write(' <height>' + str(Pheight) + '</height>\n')
xml_file.write(' <depth>' + str(Pdepth) + '</depth>\n')
xml_file.write(' </size>\n')
xml_file.write(' <object>\n')
xml_file.write(' <name>' + classes[int(oneline[0])] + '</name>\n')
xml_file.write(' <difficult>' + str(0) + '</difficult>\n')
xml_file.write(' <bndbox>\n')
xml_file.write(' <xmin>' + str(
int(((float(oneline[1])) * Pwidth + 1) - (float(oneline[3])) * 0.5 * Pwidth)) + '</xmin>\n')
xml_file.write(' <ymin>' + str(
int(((float(oneline[2])) * Pheight + 1) - (float(oneline[4])) * 0.5 * Pheight)) + '</ymin>\n')
xml_file.write(' <xmax>' + str(
int(((float(oneline[1])) * Pwidth + 1) + (float(oneline[3])) * 0.5 * Pwidth)) + '</xmax>\n')
xml_file.write(' <ymax>' + str(
int(((float(oneline[2])) * Pheight + 1) + (float(oneline[4])) * 0.5 * Pheight)) + '</ymax>\n')
xml_file.write(' </bndbox>\n')
xml_file.write(' </object>\n')
xml_file.close()
pre_img_name = img_name # 将其设为"老"图
else: # 不是新图而是"老图"
# 7.同一张图片,只需要追加写入object
xml_file = open((xml_path + img_name + '.xml'), 'a')
xml_file.write(' <object>\n')
xml_file.write(' <name>' + classes[int(oneline[0])] + '</name>\n')
xml_file.write(' <difficult>' + str(0) + '</difficult>\n')
''' 按需添加这里和上面
xml_file.write(' <pose>Unspecified</pose>\n')
xml_file.write(' <truncated>0</truncated>\n')
xml_file.write(' <difficult>0</difficult>\n')
'''
xml_file.write(' <bndbox>\n')
xml_file.write(' <xmin>' + str(
int(((float(oneline[1])) * Pwidth + 1) - (float(oneline[3])) * 0.5 * Pwidth)) + '</xmin>\n')
xml_file.write(' <ymin>' + str(
int(((float(oneline[2])) * Pheight + 1) - (float(oneline[4])) * 0.5 * Pheight)) + '</ymin>\n')
xml_file.write(' <xmax>' + str(
int(((float(oneline[1])) * Pwidth + 1) + (float(oneline[3])) * 0.5 * Pwidth)) + '</xmax>\n')
xml_file.write(' <ymax>' + str(
int(((float(oneline[2])) * Pheight + 1) + (float(oneline[4])) * 0.5 * Pheight)) + '</ymax>\n')
xml_file.write(' </bndbox>\n')
xml_file.write(' </object>\n')
xml_file.close()
# 8.读完txt文件最后写入</annotation>
xml_file1 = open((xml_path + pre_img_name + '.xml'), 'a')
xml_file1.write('</annotation>')
xml_file1.close()
print("Done !")
if __name__== '__main__':
classname_path = '' # names文件的路径
# 修改成自己的文件夹 注意文件夹最后要加上/
txt_path = ""
img_path = ""
xml_path = ""
txt_to_xml(classname_path, txt_path, img_path, xml_path)
# 修改成自己的文件夹 注意文件夹最后要加上/
# txt_to_xml("D:/西红柿数据集/tomato_train/5/txt/","D:/西红柿数据集/tomato_train/5/image/","D:/西红柿数据集/tomato_train/5/txt-xml/") #txt所在文件夹 图片所在文件夹 xml文件夹