用python批量把csv文件转化成xml文件

2022-07-31,,,,

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

《用python批量把csv文件转化成xml文件.doc》

下载本文的Word格式文档,以方便收藏与打印。