python XML文件读写解析

在目标检测中,常常要用到labelimg、labelme等标注软件。打标时往往需要打开xml文件,下面介绍利用python解析xml文件的方法。

一、读xml文件

xml文件一般格式如下:

<?xml version="1.0"?>

-<annotation>

<folder>VOC2007</folder>

<filename>d10_1597367340_img_2.jpg</filename>

<path>C:123/d10_1597367340_img_2.jpg</path>


-<source>

<database>Unknown</database>

</source>


-<size>

<width>1920</width>

<height>1080</height>

<depth>3</depth>

</size>

<segmented>0</segmented>


-<object>

<name>pig</name>

<pose>0</pose>

<truncated>0</truncated>

<difficult>0</difficult>


-<bndbox>

<xmin>860</xmin>

<ymin>733</ymin>

<xmax>1189</xmax>

<ymax>910</ymax>

</bndbox>

        XML是可扩展标记语言 ,标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。其中有且只有一个根节点,如上例中根节点为annotations,<></>是一个标签对,标签对内可以有该节点的子节点及其标签对;标签对的内容是可以自定义的。

       在用于标注数据的xml文件中,如一般根节点为annotations,包含size、folder、filename、object等多个子节点,object子结点中为bbox的信息。

xml文件读取方法:

import xml.etree.ElementTree as ET

ET为解析xml文件的专用库。

dom=ET.parse(xmlpath+item)
root=dom.getroot()
allobj=root.findall("object")

ET.parse()将xml文件读入到dom,返回一个etree对象,可以通过etree的getroot()、find()等函数对树的根节点和某个子节点进行访问。如findall("object")则返回所有的object节点,还可以通过.text()访问节点的文本属性。

二、写xml文件

写入xml文件同样是通过ET完成,

ET中的ET.Element()为创建根节点,

folder=ET.SubElement(root, "folder")则为根节点root创建子节点folder,变量名为folder

可以直接通过folder.text=str(filename)对节点内容进行赋值

tree = ET.ElementTree(root)赋值完成后通过ElementTree将所有节点返回成Tree格式

然后就可以通过tree.write(filename, xml_declaration=False, encoding='utf-8')进行保存。

下面给出创建xml文件的代码,代码中已经将写入xml定义成了类对象,可以方便的调用

class GenAnnotations:
    def __init__(self, filename, path,witdh, height, depth=3, foldername="VOC2007", database = "Unknown",seg = 0):
        self.root = ET.Element("annotation")
        self.foleder = ET.SubElement(self.root, "folder")
        self.filename = ET.SubElement(self.root, "filename")
        self.path = ET.SubElement(self.root,"path")
        self.source = ET.SubElement(self.root, "source")
        self.database = ET.SubElement(self.source,"database")
        self.size = ET.SubElement(self.root, "size")
        self.width = ET.SubElement(self.size, "width")
        self.height = ET.SubElement(self.size, "height")
        self.depth = ET.SubElement(self.size, "depth")
        self.segmented = ET.SubElement(self.root,"segmented")

        self.foleder.text = foldername
        self.filename.text = filename
        self.path.text = path
        self.database.text = database
        self.width.text = str(witdh)
        self.height.text = str(height)
        self.depth.text = str(depth)
        self.segmented.text = str(seg)

    def savefile(self, filename):
        tree = ET.ElementTree(self.root)
        tree.write(filename, xml_declaration=False, encoding='utf-8')

    def add_object(self, label, xmin, ymin, xmax, ymax, tpose=0, ttruncated=0, tdifficult=0):
        object = ET.SubElement(self.root, "object")
        namen = ET.SubElement(object, "name")
        namen.text = label
        pose = ET.SubElement(object, "pose")
        pose.text = str(tpose)
        truncated = ET.SubElement(object, "truncated")
        truncated.text = str(ttruncated)
        difficult = ET.SubElement(object, "difficult")
        difficult.text = str(tdifficult)
        bndbox = ET.SubElement(object, "bndbox")
        xminn = ET.SubElement(bndbox, "xmin")
        xminn.text = str(xmin)
        yminn = ET.SubElement(bndbox, "ymin")
        yminn.text = str(ymin)
        xmaxn = ET.SubElement(bndbox, "xmax")
        xmaxn.text = str(xmax)
        ymaxn = ET.SubElement(bndbox, "ymax")
        ymaxn.text = str(ymax)


if __name__ == '__main__':
  

   anno= GenAnnotations(filename,path, 1920, 1080)
   with open (txtpath+item,'r',encoding='utf-8') as files:
###给出要写入的参数,可以从其他格式的标签中直接读取,pig为目标类别
        anno.add_object("pig",xmin,ymin,xmax,ymax)
        anno.savefile(xmlpath+item.split('.')[0]+'.xml')

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DZZ!!!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值