用python批量把csv文件转化成xml文件
程序员文章站
2022-03-05 13:18:11
CSV文件(目标检测,单个图片对应单个文件、多个目标)转xml文件有目标的csv文件:无目标的csv文件:读取csv并写入xml(创建新的xml)#编辑xml文件的函数def csvtoxml(fname): with open(fname, 'r') as f: reader = csv.reader(f) #读取csv文件 a = Element('annotation') b = SubElement(a, 'fol...
CSV文件(目标检测,单个图片对应单个文件、多个目标)转xml文件
有目标的csv文件:
无目标的csv文件:
读取csv并写入xml(创建新的xml)
#编辑xml文件的函数
def csvtoxml(fname):
with open(fname, 'r') as f:
reader = csv.reader(f) #读取csv文件
a = Element('annotation')
b = SubElement(a, 'folder')
b.text = 'label'
c = SubElement(a, 'filename')
c.text=str(fname)[-40:-4]+'.jpg' #字符串化路径,截取名称并加上格式
c_1 = SubElement(a, 'path')
c_1.text = 'D:/untitled/.idea/CenterNet/medic_train/%s' %c.text
d = SubElement(a, 'source')
d_1 =SubElement(d,'databases')
d_1.text='Unknown'
e=SubElement(a,'size') #图片的大小
e_1,e_2,e_3 = SubElement(e,'width'),SubElement(e,'height'),SubElement(e,'depth')
e_1.text,e_2.text,e_3.text='1024','1024','3'
f=SubElement(a,'segmented')
f.text='0'
#通过csv文件的内容写入xml文件
for row in islice(reader,1,None): #islice的作用为去掉第一行(即表头)
list=[] #方便之后bbox坐标赋值
# 比较复杂的object模块
g = SubElement(a, 'object')
g_1, g_2, g_3,g_4 = SubElement(g, 'name'), SubElement(g, 'pose'), \
SubElement(g, 'truncated'),SubElement(g, 'difficult')
h=SubElement(g,'bndbox') #bbox的坐标
h_1, h_2, h_3,h_4 = SubElement(h, 'xmin'), SubElement(h, 'ymin'), SubElement(h, 'xmax'),SubElement(h, 'ymax')
for text in row:
list.append(text)
# 利用列表给bbox坐标赋值
if list[1]!='': #判断元素是否为空
h_1.text, h_2.text, h_3.text, h_4.text=list[1],list[2],\
str(float(list[1])+float(list[3])),\
str(float(list[2])+float(list[4]))
else:
h_1.text, h_2.text, h_3.text, h_4.text = list[1], list[2], list[3], list[4]
print(list)
#判断是否为肺炎(取决于csv中的Target是否为1)
if row[-1]=="1":
judge='Lung Opacity'
else:
judge = 'No Lung Opacity'
g_1.text, g_2.text, g_3.text, g_4.text = judge, 'Unspecified', '0', '0'
#打印出
print(str(c.text)+' ----> True')
return ElementTree(a)
其中读取csv文件时为了去表头,用了islice
该大佬的博客:https://www.tuziang.com/combat/716.html
for row in islice(reader,1,None):
因为csv中的数据是以左上角坐标x,y和框的长宽,所以转化为标准的ymax,xmax等形式
先判断是否为空,否则不能转换成float进行加法运算
# 利用列表给bbox坐标赋值
if list[1]!='': #判断元素是否为空
h_1.text, h_2.text, h_3.text, h_4.text=list[1],list[2],\
str(float(list[1])+float(list[3])),\
str(float(list[2])+float(list[4]))
else:
h_1.text, h_2.text, h_3.text, h_4.text = list[1], list[2], list[3], list[4]
遍历文件夹中的csv文件:
#遍历该文件夹
for filename in os.listdir(r"%s" % way_1):
name = filename[:-4]
tree=csvtoxml(r'%s\%s.csv'%(way_1,name))
tree.write('%s/%s.xml'% (way_2,name), encoding='UTF-8')
完整代码:
from xml.etree.ElementTree import Element, ElementTree, tostring,SubElement
from itertools import islice #方便csv文件去表头工作
import argparse
import os
import csv
'''
整体思路很简单,利用SubElement来搭建xml文件中的模块。
就像搭积木那样
本代码利用了每张图片所对应的csv文件(单个)
也就是csv到xml
'''
#编辑xml文件的函数
def csvtoxml(fname):
with open(fname, 'r') as f:
reader = csv.reader(f) #读取csv文件
a = Element('annotation')
b = SubElement(a, 'folder')
b.text = 'label'
c = SubElement(a, 'filename')
c.text=str(fname)[-40:-4]+'.jpg' #字符串化路径,截取名称并加上格式
c_1 = SubElement(a, 'path')
c_1.text = 'D:/untitled/.idea/CenterNet/medic_train/%s' %c.text
d = SubElement(a, 'source')
d_1 =SubElement(d,'databases')
d_1.text='Unknown'
e=SubElement(a,'size') #图片的大小
e_1,e_2,e_3 = SubElement(e,'width'),SubElement(e,'height'),SubElement(e,'depth')
e_1.text,e_2.text,e_3.text='1024','1024','3'
f=SubElement(a,'segmented')
f.text='0'
#通过csv文件的内容写入xml文件
for row in islice(reader,1,None): #islice的作用为去掉第一行(即表头)
list=[] #方便之后bbox坐标赋值
# 比较复杂的object模块
g = SubElement(a, 'object')
g_1, g_2, g_3,g_4 = SubElement(g, 'name'), SubElement(g, 'pose'), \
SubElement(g, 'truncated'),SubElement(g, 'difficult')
h=SubElement(g,'bndbox') #bbox的坐标
h_1, h_2, h_3,h_4 = SubElement(h, 'xmin'), SubElement(h, 'ymin'), SubElement(h, 'xmax'),SubElement(h, 'ymax')
for text in row:
list.append(text)
# 利用列表给bbox坐标赋值
if list[1]!='': #判断元素是否为空
h_1.text, h_2.text, h_3.text, h_4.text=list[1],list[2],\
str(float(list[1])+float(list[3])),\
str(float(list[2])+float(list[4]))
else:
h_1.text, h_2.text, h_3.text, h_4.text = list[1], list[2], list[3], list[4]
#判断是否为肺炎(取决于csv中的Target是否为1)
if row[-1]=="1":
judge='Lung Opacity'
else:
judge = 'No Lung Opacity'
g_1.text, g_2.text, g_3.text, g_4.text = judge, 'Unspecified', '0', '0'
#打印出
print(str(c.text)+' ----> True')
return ElementTree(a)
#方便引入文件、路径
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--csv_label', type=str, default='D:/untitled/.idea/CenterNet/label_csv', help='input label')
parser.add_argument('--xml_label', type=str, default='D:/untitled/.idea/CenterNet/label_xml', help='ouput label')
opt=parser.parse_args()
way_1=opt.csv_label
way_2=opt.xml_label
print(opt)
#遍历该文件夹
for filename in os.listdir(r"%s" % way_1):
name = filename[:-4]
tree=csvtoxml(r'%s\%s.csv'%(way_1,name))
tree.write('%s/%s.xml'% (way_2,name), encoding='UTF-8')
转化后有目标的文件:
转化后没有目标的文件:
xml文件格式参考labellmg标注工具所得到的xml文件:
转化前的批量csv文件:
转化后:
本文地址:https://blog.csdn.net/you2336/article/details/107672077
推荐阅读