先上代码:
import os
import sys
import xml.etree.ElementTree as ET
import glob
def xml_to_txt(indir,outdir):
os.chdir(indir)
annotations = os.listdir('.')
annotations = glob.glob(str(annotations)+'*.xml')
print(annotations)
for i, file in enumerate(annotations):
file_save = file.split('.')[0]+'.txt'
# file_txt=os.path.join(outdir,file_save)
file_txt = outdir+"/"+file_save
# print(file_save)
f_w = open(file_txt, 'w')
# actual parsing
in_file = open(file,'rb')
tree=ET.parse(in_file)
root = tree.getroot()
filename = root.find('filename').text #这里是xml的根,获取filename那一栏
for obj in root.iter('object'):
current = list()
name = obj.find('name').text #这里获取多个框的名字,底下是获取每个框的位置
#如果是<>属性<>,就先obj.find('<>里的内容')
#如果不是,就root.find('<>里的内容')
a = root.find('size')
w1 = float(a.find('width').text)
h1 = float(a.find('height').text)
#不需要相对位置就不用转为float型
#转换是为了后面的计算
xmlbox = obj.find('bndbox')
xn = float(xmlbox.find('xmin').text)
xx = float(xmlbox.find('xmax').text)
yn = float(xmlbox.find('ymin').text)
yx = float(xmlbox.find('ymax').text)
#绝对坐标改相对坐标
x_center = (xn+xx)/(2*w1)
y_center = (yn+yx)/(2*h1)
w = (xx-xn)/w1
h = (yx-yn)/h1
if name=='mask':
label = '1'
else:
label = '0'
#这里根据自己目标txt文件的格式改
f_w.write(label +' '+str(x_center)+' '+str(y_center)
+' '+str(w)+' '+str(h)+' ')
f_w.write('\n')
indir='xml绝对路径' #xml目录
outdir='txt绝对路径' #txt目录
xml_to_txt(indir,outdir)
如果报下面的错(马赛克部分是我的本地路径,不影响参考)
那就先创建目标目录和第一个xml文件的同名空白txt文件就OK
参考:
yolo坐标归一化
我主要是根据下面这位朋友的链接改的,容易错的part已经标注了,代码上面的标注是我的,代码右边的注释是这位朋友原来的。
python目标检测xml转txt