欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

用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文件:
用python批量把csv文件转化成xml文件
无目标的csv文件:
用python批量把csv文件转化成xml文件


读取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')

转化后有目标的文件:
用python批量把csv文件转化成xml文件
转化后没有目标的文件:
用python批量把csv文件转化成xml文件
xml文件格式参考labellmg标注工具所得到的xml文件:
用python批量把csv文件转化成xml文件
转化前的批量csv文件:
用python批量把csv文件转化成xml文件
转化后:
用python批量把csv文件转化成xml文件

本文地址:https://blog.csdn.net/you2336/article/details/107672077