两种不同风格的lxml标注文件的解析:pet和Lara_UrbanSeq1_Traffic Light

2024-02-12 04:32

本文主要是介绍两种不同风格的lxml标注文件的解析:pet和Lara_UrbanSeq1_Traffic Light,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. pet数据集标注样式

以Abyssinian_12.xml为例,文件内容如下:

<annotation><folder>OXIIIT</folder><filename>Abyssinian_12.jpg</filename><source><database>OXFORD-IIIT Pet Dataset</database><annotation>OXIIIT</annotation><image>flickr</image></source><size><width>335</width><height>500</height><depth>3</depth></size><segmented>0</segmented><object><name>cat</name><pose>Frontal</pose><truncated>0</truncated><occluded>0</occluded><bndbox><xmin>94</xmin><ymin>83</ymin><xmax>211</xmax><ymax>190</ymax></bndbox><difficult>0</difficult></object>
</annotation>

分析可知,其节点全部为tag:text形式,每个tag不包含attrib。因此,参照Object Detection API官方,采用以下方式来进行递归读取,返回一个包含多层级字典结构的数据。

import numpy as np
import PIL.Image
import tensorflow as tf
from lxml import etreefrom object_detection.dataset_tools import tf_record_creation_util
from object_detection.utils import dataset_util
from object_detection.utils import label_map_utilxml_path = "./Annotations/Abyssinian_12.xml"
# xml_path = "./Annotations/Lara_test.xml"with tf.gfile.GFile(xml_path, 'r') as fid:xml_str = fid.read()xml = etree.fromstring(xml_str)
#     xml = etree.fromstring(xml_str.encode('utf-8'))data = dataset_util.recursive_parse_xml_to_dict(xml)['annotation']
#     data = dataset_util.recursive_parse_xml_to_dict(xml)print(data)
#     for item in data:
#         print(type(item))

其中调用的函数recursive_parse_xml_to_dict(xml)如下:

def recursive_parse_xml_to_dict(xml):"""Recursively parses XML contents to python dict.We assume that `object` tags are the only ones that can appearmultiple times at the same level of a tree.Args:xml: xml tree obtained by parsing XML file contents using lxml.etreeReturns:Python dictionary holding XML contents."""if not xml:return {xml.tag: xml.text}result = {}for child in xml:child_result = recursive_parse_xml_to_dict(child)if child.tag != 'object':result[child.tag] = child_result[child.tag]else:if child.tag not in result:result[child.tag] = []result[child.tag].append(child_result[child.tag])return {xml.tag: result}

2. Lara标注样式

Lara交通标志数据集的标注文件将所有的图片文件信息整合在一个文件中,截取一段如下:

<?xml version="1.0" encoding="UTF-8"?>
<dataset name="Lara_UrbanSeq1" version="0.5" comments="Public database: http://www.lara.prd.fr/benchmarks/trafficlightsrecognition"><frame number="6695" sec="487" ms="829"><objectlist><object id="18"><orientation>90</orientation><box h="39" w="18" xc="294" yc="34"/><appearance>appear</appearance><hypothesislist><hypothesis evaluation="1.0" id="1" prev="1.0"><type evaluation="1.0">Traffic Light</type><subtype evaluation="1.0">go</subtype></hypothesis></hypothesislist></object><object id="19"><orientation>90</orientation><box h="15" w="6" xc="518" yc="123"/><appearance>appear</appearance><hypothesislist><hypothesis evaluation="1.0" id="1" prev="1.0"><type evaluation="1.0">Traffic Light</type><subtype evaluation="1.0">go</subtype></hypothesis></hypothesislist></object><object id="20"><orientation>90</orientation><box h="15" w="6" xc="382" yc="122"/><appearance>appear</appearance><hypothesislist><hypothesis evaluation="1.0" id="1" prev="1.0"><type evaluation="1.0">Traffic Light</type><subtype evaluation="1.0">go</subtype></hypothesis></hypothesislist></object></objectlist><grouplist></grouplist></frame>
</dataset>

可见其主要信息都包含在tag:attrib中,是难以用递归函数来实现解析的。
对该文件进行单独测试如下:

# 测试解析xml文件
# examples_path = os.path.join(annotations_dir, 'trainval.txt')
# examples_list = dataset_util.read_examples_list(examples_path)
# xml_path = "./Annotations/Lara_UrbanSeq1_GroundTruth_cvml.xml"
# tree = ET.parse(xml_path)
# root = tree.getroot()
# print(root.tag)
# print(root.attrib)
# print(root[11178].tag)
# print(root[11178].attrib)
# print(root[11178][0][0].tag)
# print(root[11178][0][0].attrib)
# for frame in root.findall("./frame")
# for obj in root[11178][0][0]:
#     print(obj.attrib)
#     print(obj.tag)

主要实现代码如下:

# 从xml文件解析出数据,以list形式返回。每个list的item都是包含相关信息的一个dict
def get_data_list(xml_path, label_map_dict):"""Function: parse xml to a list of image data, every item contain a dict of image name, size, and a list of objects.Args:xml_path: the path to the xml fileReturns:data_list: a list of data, every data is a dict contain keys.{   'filename': 'frame_006630.jpg', 'size':    {'width': 640, 'height': 480}, 'object':  [ {'bndbox': {'xmin': 368, 'xmax': 378, 'ymin': 94, 'ymax': 116}}, {'bndbox': {'xmin': 563, 'xmax': 571, 'ymin': 103, 'ymax': 123}}]}"""tree = ET.parse(xml_path)root = tree.getroot()data_list = []for frame in root.findall('./frame'):frame_number = int(frame.get("number"))img_name = "frame_{0:06d}.jpg".format(frame_number) # 得到第一个字段,文件名data = dict()data['filename']=img_nameimg_size = dict()img_size['width']=640img_size['height']=480data['size']=img_sizeobject_list=[]data['object']=object_listfor obj in frame.findall('./objectlist/object'): # 得到该帧里的每个objectobject = dict()# 这里待验证。暂时仍用读到的字符串,而没有转换为数字class_name = obj.find('./hypothesislist/hypothesis/subtype').text
#             classes_text.append(class_name.encode('utf-8'))
#             classes.append(label_map_dict[class_name])object['class_text'] = class_nameobject['class_id'] = label_map_dict[class_name]obj_h = int(obj.find('box').get("h"))    obj_w = int(obj.find('box').get("w"))obj_xc = int(obj.find('box').get("xc"))obj_yc = int(obj.find('box').get("yc"))xmin = obj_xc-int(obj_w//2)if xmin<0:xmin=0xmax = obj_xc+int(obj_w//2)ymin = obj_yc-int(obj_h//2)if ymin<0:ymin=0ymax = obj_yc+int(obj_h//2)bndbox = dict()            bndbox['xmin'] = xminbndbox['xmax'] = xmaxbndbox['ymin'] = yminbndbox['ymax'] = ymaxobject['bndbox'] = bndboxobject_list.append(object)data_list.append(data)return data_list

3. 主要对比

前者使用lxml.etree,后者使用xml.etree.ElementTree。解析过程不同。

这篇关于两种不同风格的lxml标注文件的解析:pet和Lara_UrbanSeq1_Traffic Light的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/701668

相关文章

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

关于Spring @Bean 相同加载顺序不同结果不同的问题记录

《关于Spring@Bean相同加载顺序不同结果不同的问题记录》本文主要探讨了在Spring5.1.3.RELEASE版本下,当有两个全注解类定义相同类型的Bean时,由于加载顺序不同,最终生成的... 目录问题说明测试输出1测试输出2@Bean注解的BeanDefiChina编程nition加入时机总结问题说明

C语言中自动与强制转换全解析

《C语言中自动与强制转换全解析》在编写C程序时,类型转换是确保数据正确性和一致性的关键环节,无论是隐式转换还是显式转换,都各有特点和应用场景,本文将详细探讨C语言中的类型转换机制,帮助您更好地理解并在... 目录类型转换的重要性自动类型转换(隐式转换)强制类型转换(显式转换)常见错误与注意事项总结与建议类型

MySQL 缓存机制与架构解析(最新推荐)

《MySQL缓存机制与架构解析(最新推荐)》本文详细介绍了MySQL的缓存机制和整体架构,包括一级缓存(InnoDBBufferPool)和二级缓存(QueryCache),文章还探讨了SQL... 目录一、mysql缓存机制概述二、MySQL整体架构三、SQL查询执行全流程四、MySQL 8.0为何移除查

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

在Rust中要用Struct和Enum组织数据的原因解析

《在Rust中要用Struct和Enum组织数据的原因解析》在Rust中,Struct和Enum是组织数据的核心工具,Struct用于将相关字段封装为单一实体,便于管理和扩展,Enum用于明确定义所有... 目录为什么在Rust中要用Struct和Enum组织数据?一、使用struct组织数据:将相关字段绑

使用Java实现一个解析CURL脚本小工具

《使用Java实现一个解析CURL脚本小工具》文章介绍了如何使用Java实现一个解析CURL脚本的工具,该工具可以将CURL脚本中的Header解析为KVMap结构,获取URL路径、请求类型,解析UR... 目录使用示例实现原理具体实现CurlParserUtilCurlEntityICurlHandler

Python中连接不同数据库的方法总结

《Python中连接不同数据库的方法总结》在数据驱动的现代应用开发中,Python凭借其丰富的库和强大的生态系统,成为连接各种数据库的理想编程语言,下面我们就来看看如何使用Python实现连接常用的几... 目录一、连接mysql数据库二、连接PostgreSQL数据库三、连接SQLite数据库四、连接Mo