• Python解析VOC数据标签文件


    导读

    在目标检测数据集中我们经常会使用到VOC格式的数据,这篇文章就向大家介绍一下如何来解析xml标签文件的数据

    xml数据

    <annotation>
      <folder>/root/datasets</folder>
      <filename>/root/datasets/example/example.jpg</filename>
      <source>
        <database>Unknown</database>
        <annotation>Unknown</annotation>
        <image>Unknown</image>
      </source>
      <size>
        <width>1080</width>
        <height>1440</height>
        <depth></depth>
      </size>
      <segmented>0</segmented>
      <object>
        <name>1</name>
        <occluded>0</occluded>
        <bndbox>
          <xmin>767.78</xmin>
          <ymin>65.87</ymin>
          <xmax>792.08</xmax>
          <ymax>102.33</ymax>
        </bndbox>
      </object>
      <object>
        <name>2</name>
        <occluded>0</occluded>
        <bndbox>
          <xmin>378.89</xmin>
          <ymin>546.77</ymin>
          <xmax>403.19</xmax>
          <ymax>583.23</ymax>
        </bndbox>
      </object>
    </annotation>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    解析xml数据

    python的xml库提供了几种不同的方法来解析xml文件,下面我们来介绍如何通过ElementTreeminidom来解析xml文件

    使用ElementTree解析xml数据

    通过ElementTree解析xml数据主要分为下面几个步骤:

    1. 使用getroot方法来获取xml的根节点信息
    2. 使用find方法来找到不需要遍历节点的信息
    3. 通过iter来编译包含多个相同节点的信息
    import xml.etree.ElementTree as ET
    
    def parse_xml(xml_path):
        #读取xml文件
        rf = open(xml_path,"r")
        #开始解析xml文件
        tree = ET.parse(rf)
        #获取根节点信息
        root = tree.getroot()
    
        #获取图片的路径
        img_path = root.find("filename").text
        #获取图片的size节点的信息
        size = root.find("size")
        #获取图片的宽
        img_width = size.find("width").text
        #获取图片的高
        img_height = size.find("height").text
    
        #解析图片的box信息
        #遍历object节点的信息
        label_infos = []
        for object in root.iter("object"):
            #获取类别的名称
            name = object.find("name").text
            #获取标签的识别难度
            occluded = object.find("occluded").text
            #获取标签的box信息
            bndbox = object.find("bndbox")
            xmin = float(bndbox.find('xmin').text)
            xmax = float(bndbox.find('xmax').text)
            ymin = float(bndbox.find('ymin').text)
            ymax = float(bndbox.find('ymax').text)
            box = (xmin,xmax,ymin,ymax)
            label_infos.append((name,occluded,box))
        return label_infos,img_width,img_height
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    使用minidom来解析xml文件

    使用minidom来解析xml相对于ElementTree来说要稍微复杂一点,minidom主要通过getElementsByTagName函数来寻找节点,然后再通过childNodes来逐步解析xml文件,我将minidom解析xml文件以及封装成了三个函数:

    1. get_all_node获取节点下面所有的子节点
    2. get_node_value获取节点的值
    3. get_node_name获取节点的名称
    from xml.dom import minidom
    
    def parse_xml_by_minidom(xml_path):
    
        def get_node_name(node):
            """获取节点的名字
            :param node:
            :return:
            """
            return node.nodeName
    
    
        def get_node_value(node):
            """获取node的值
            :param node:
            :return:
            """
            child_nodes = node.childNodes
            return child_nodes[0].nodeValue
    
        def get_all_node(node,node_list):
            """获取所有的节点
            :param node:
            :param node_list:
            :return:
            """
            for child_node in node.childNodes:
                if isinstance(child_node,minidom.Element):
                    child_nodes = child_node.childNodes
                    if len(child_nodes) == 1:
                        node_list.append(child_node)
                    else:
                        get_all_node(child_node,node_list)
    
    
        def get_all_child_value(node):
            """获取节点所有子节点信息
            :param node:
            :return:
            """
            node_list = []
            get_all_node(node,node_list)
            node_info = {}
            for node in node_list:
                node_name = get_node_name(node)
                node_value = get_node_value(node)
                if node_value is not None:
                    node_info[node_name] = node_value
            return node_info
    
    
        doc = minidom.parse(xml_path)
        #获取跟节点
        root = doc.documentElement
        #获取图片的路径
        img_path_node = root.getElementsByTagName("filename")[0]
        #获取节点的名称
        node_name = get_node_name(img_path_node)
        #获取节点的值
        img_path = get_node_value(img_path_node)
        size_node_list = root.getElementsByTagName("size")
        size_info = get_all_child_value(size_node_list[0])
        #获取图片的宽和高
        img_width = size_info["width"]
        img_height = size_info["height"]
        #获取标签信息
        box_info_list = []
        object_node_list = root.getElementsByTagName("object")
        for object_node in object_node_list[:1]:
            box_node_info = get_all_child_value(object_node)
            box_info_list.append(box_node_info)
        return box_info_list,img_width,img_height
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
  • 相关阅读:
    【信创】 JED on 鲲鹏(ARM) 调优步骤与成果
    C++对象内存布局
    存储过程、Statement详解
    redux-react多组件进行数据共享
    CPU组成与流水线设计——嵌入式第二章课后习题
    【微信小程序】数字化会议OA系统之投票模块(附源码)
    【Hack The Box】linux练习-- Blunder
    机器学习中参数优化调试方法
    4 OpenCV实现多目三维重建(多张图片增量式生成稀疏点云)【附源码】
    【设计模式】单例模式的8种实现方式
  • 原文地址:https://blog.csdn.net/sinat_29957455/article/details/126083678