用python将CSV标签文件(批量)转换为XML文件(单个)

博主是基于2021小麦目标检测以及计数比赛提供官方数据集作为例子,将官方提供的含有大量标签的CSV文件转换为VOC格式的XML标注文件,方便算法进行训练。

1、比赛地址以及概况:

2021年全球小麦目标检测计数比赛
在这里插入图片描述


2、图像数据集:

在这里插入图片描述
在这里插入图片描述


3、标签文件数据集:

在这里插入图片描述


4、转换代码:

编辑XML文件的函数需要用到xml.etree.ElementTree的函数进行字符串数据的写入,在这里博主编写csvtoxml函数,以图像名、标注框四个坐标、域(domain)作为输入,输出为XML文件信息树,便于接下来的保存。

#编辑xml文件的函数
def csvtoxml(image_name,bbox,domain):

    a = Element('annotation')

    b = SubElement(a, 'folder')
    b.text = 'label'

    c = SubElement(a, 'filename')
    c.text=image_name+'.png'

    c_1 = SubElement(a, 'path')
    c_1.text = 'D:/Download/2021wheat_object_dectection/train/%s' %c.text

    d = SubElement(a, 'source')
    d_1 =SubElement(d,'databases')
    d_1.text='Unknown'
    d_2 =SubElement(d,'domain')
    d_2.text = '%s'%domain

    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'

    #依据;分离标准框坐标
    str_bbox=bbox.split(";")


    #读取每个目标的标注框坐标
    for i in str_bbox:

        #分离每个标准框的四个坐标点
        list_point=i.split()

        # 定义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')

        # 定义bbox的坐标格式
        h=SubElement(g,'bndbox')
        h_1, h_2, h_3,h_4 = SubElement(h, 'xmin'), SubElement(h, 'ymin'), SubElement(h, 'xmax'),SubElement(h, 'ymax')

        #目标类别为单类别“小麦”
        judge = 'Wheat'
        h_1.text, h_2.text, h_3.text, h_4.text = list_point[0], list_point[1], list_point[2], list_point[3]
        g_1.text, g_2.text, g_3.text, g_4.text = judge, 'Unspecified', '0', '0'

    return ElementTree(a)

主函数main则是负责挑出CSV文件中不含标注框(bbox)的标签,利用迭代将标签信息输送给csvtoxml

def main():
    #读取csv文件,不读取表头
    df=pd.read_csv(way_1,header=None)
    #读取csv中数据的行数
    index_num=len(df.index)

    for i in tqdm(range(1,index_num)):
        # print(i)

        row_data_1=df.iloc[i]     #1到3657

        image_name=row_data_1[0]
        bbox=row_data_1[1]
        domain=row_data_1[2]

        if bbox !='no_box':
            tree=csvtoxml(image_name,bbox,domain)
            tree.write('%s/%s.xml' % (way_2, image_name), encoding='UTF-8')

整个py文件的完整的代码如下。

import csv
import argparse
import numpy as np
import pandas as pd
from tqdm import tqdm
from xml.etree.ElementTree import Element, ElementTree, tostring,SubElement


parser = argparse.ArgumentParser()
parser.add_argument('--big_csv', type=str, default='D:/Download/2021wheat_object_dectection/train.csv', help='')
parser.add_argument('--csv_way', type=str, default='D:/Download/2021wheat_object_dectection/label_xml', help='')
opt=parser.parse_args()

way_1=opt.big_csv
way_2=opt.csv_way
print(opt)


#编辑xml文件的函数
def csvtoxml(image_name,bbox,domain):

    a = Element('annotation')

    b = SubElement(a, 'folder')
    b.text = 'label'

    c = SubElement(a, 'filename')
    c.text=image_name+'.png'

    c_1 = SubElement(a, 'path')
    c_1.text = 'D:/Download/2021wheat_object_dectection/train/%s' %c.text

    d = SubElement(a, 'source')
    d_1 =SubElement(d,'databases')
    d_1.text='Unknown'
    d_2 =SubElement(d,'domain')
    d_2.text = '%s'%domain

    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'

    #依据;分离标准框坐标
    str_bbox=bbox.split(";")


    #读取每个目标的标注框坐标
    for i in str_bbox:

        #分离每个标准框的四个坐标点
        list_point=i.split()

        # 定义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')

        # 定义bbox的坐标格式
        h=SubElement(g,'bndbox')
        h_1, h_2, h_3,h_4 = SubElement(h, 'xmin'), SubElement(h, 'ymin'), SubElement(h, 'xmax'),SubElement(h, 'ymax')

        #目标类别为单类别“小麦”
        judge = 'Wheat'
        h_1.text, h_2.text, h_3.text, h_4.text = list_point[0], list_point[1], list_point[2], list_point[3]
        g_1.text, g_2.text, g_3.text, g_4.text = judge, 'Unspecified', '0', '0'

    return ElementTree(a)




def main():
    #读取csv文件,不读取表头
    df=pd.read_csv(way_1,header=None)
    #读取csv中数据的行数
    index_num=len(df.index)

    for i in tqdm(range(1,index_num)):
        # print(i)

        row_data_1=df.iloc[i]     #1到3657

        image_name=row_data_1[0]
        bbox=row_data_1[1]
        domain=row_data_1[2]

        if bbox !='no_box':
            tree=csvtoxml(image_name,bbox,domain)
            tree.write('%s/%s.xml' % (way_2, image_name), encoding='UTF-8')



if __name__ == '__main__':
    main()


5、转换效果:

在这里插入图片描述
在这里插入图片描述


6、标签可视化:

关于标签可视化,博主有一篇编码好的py文件,可以改一下路径直接拿来用,色彩等细节可以自己调。

XML可视化(将标注框标注到数据集中显示处理并保存)

可视化效果也挺好的。
在这里插入图片描述

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值