使用python创建、添加、修改xml格式的标注文件

在深度学习目标检测的所用到的数据集中,常会遇到xml格式的标注文件(例如VOC格式的数据集采用的标注文件就是xml格式的)。在我们自己建立xml标注文件或者是将其他类型的标注文件(例如txt、json)转化到xml格式时,就需要了解这方面的知识。

下面我将列出用python借助lxml来进行xml类型文件的创建、添加、修改功能的实现代码。

1.创建xml格式的标注文件

下面展示创建xml格式文件的代码及运行代码后生成的xml文件的内容效果图,这里我们先简单创立一个xml文件,设定根节点、为根节点添加几个子节点、并给节点起名、设定节点包含的文本text信息。

代码如下:

from lxml.etree import Element, tostring, parse
from lxml.etree import SubElement as subElement
def xml_construct(save_path,folder,filename,path,width=800,height=600,depth = 3,segmented=0):
    default_text = 'default'
    node_root = Element('annotation')  # 根节点

    node_folder = subElement(node_root, 'folder')  # 在节点下添加名为'folder'的子节点
    node_folder.text = folder  # 设定节点的文字

    node_filename = subElement(node_root, 'filename')
    node_filename.text = filename

    node_path = subElement(node_root, 'path')
    node_path.text = path

    node_size = subElement(node_root, 'size')
    node_size_width = subElement(node_size, 'width')
    node_size_width.text = '%s' % int(width)
    node_size_height = subElement(node_size, 'height')
    node_size_height.text = '%s' % int(height)
    node_size_depth = subElement(node_size, 'depth')
    node_size_depth.text = '%s' % int(depth)

    node_segmented = subElement(node_root, 'segmented')
    node_segmented.text = '%s' % int(segmented)

    xml = tostring(node_root, pretty_print=True) #将上面设定的一串节点信息导出
    with open(save_path,'wb') as f: #将节点信息写入到文件路径save_path中
        f.write(xml)

    return

#----------调用上面所写的函数进行试验,创建名为test.xml的xml文件----------
xml_construct('test.xml','test','test','test',width=1600,height=1200,)

运行以上代码结果为:

2.为已存在的xml文件进行添加节点

在这里我们展示如何对已存在的xml文件进行添加节点操作,我们接着在上一步骤中生成的test.xml上面来进行修改。

代码如下:
 

from lxml.etree import Element, tostring, parse
from lxml.etree import SubElement as subElement
def xml_add_object(xml_path,name,id,xmin,ymin,xmax,ymax,pose = 'Unspecified',truncated=0,difficult=0):
    tree = parse(xml_path)  # 读取xml文件
    node_root = tree.getroot()  # 找到xml文件的根节点
    node_object = subElement(node_root, 'object')  #在根节点node_root下面添加名为'object'的子节点
    node_object_name = subElement(node_object, 'name') #在根节点node_root的子节点object下面继续添加子节点object的子节点'name'
    node_object_name.text = name #设定该节点的文本text信息
    node_object_id = subElement(node_object, 'id')
    node_object_id.text = '%s' % int(id)
    node_object_pose = subElement(node_object, 'pose')
    node_object_pose.text = pose
    node_object_truncated = subElement(node_object, 'truncated')
    node_object_truncated.text = '%s' % int(truncated)
    node_object_difficult = subElement(node_object, 'difficult')
    node_object_difficult.text = '%s' % int(difficult)
    # object坐标
    node_bndbox = subElement(node_object, 'bndbox')
    node_xmin = subElement(node_bndbox, 'xmin')
    node_xmin.text = '%s' % int(xmin)
    node_ymin = subElement(node_bndbox, 'ymin')
    node_ymin.text = '%s' % int(ymin)
    node_xmax = subElement(node_bndbox, 'xmax')
    node_xmax.text = '%s' % int(xmax)
    node_ymax = subElement(node_bndbox, 'ymax')
    node_ymax.text = '%s' % int(ymax)

    xml = tostring(node_root, pretty_print=True) #将修改后的xml节点信息导出

    with open(xml_path,'wb') as f: #将修改后的xml节点信息覆盖掉修改前的
        f.write(xml)

    return

#----------试验,在test.xml中进行添加节点操作----------
xml_add_object(xml_path='test.xml',name='test_name',id=999,xmin=1,ymin=2,xmax=3,ymax=4,)

运行以上代码后原先的test.xml文件就被添加了相应的子节点,效果如下:

3.修改已存在的xml文件中特定节点的信息

如果我们只想的对xml文件中某些特定节点信息进行修改的话,可以进行一下代码操作(这里我们还是以上面的test.xml文件为操作对象,将其中的size节点下的width和height节点信息进行修改):

from lxml.etree import Element, tostring, parse
from lxml.etree import SubElement as subElement
def modify_size(xml_path,size_width=800,size_height=600):
    tree = parse(xml_path)
    width = tree.xpath('//width')#这里返回的width是一个包含所有名称中带有"width"的节点的列表
    for width_i in width:
        width_i.text = '%s' % int(size_width) #这里直接写width_i.text = size_width会报错

    height = tree.xpath('//height')
    for height_i in height:
        height_i.text = '%s' % int(size_height)

    node_root = tree.getroot()
    xml = tostring(node_root, pretty_print=True)
    with open(xml_path,'wb') as f:
        f.write(xml)

    return

#----------试验----------
#以上面的test.xml文件为操作对象,将其中的size节点下的width和height节点信息进行修改
modify_size('test.xml',size_width=800,size_height=600)

效果如下:

猜你喜欢

转载自blog.csdn.net/qq_40641713/article/details/127537245