文章目录

  • 什么是xml
  • xml解析讲解
    • 一、标签介绍
      • filename标签
      • size标签
      • object标签
    • 二、xml解析的API
  • xml单个文件的解析
    • 构建类别索引(category_id)
    • 构建xml解析
    • 代码测试

什么是xml

XML 被设计用来传输和存储数据。
XML于HTML的标签语言类似,都是使用标签来进行约束!【相对于html标签,xml标签可以自定义
(对于上面的定义,我们简单了解一下就可以了,并不会对我们解析它有影响!)
下面展示一份简单的xml文件!(AI识虫的一份用于存储目标检测相关数据的xml文件)

<annotation><folder>刘霏霏</folder><filename>1.jpeg</filename><path>/home/fion/桌面/刘霏霏/1.jpeg</path><source><database>Unknown</database></source><size><width>1344</width><height>1344</height><depth>3</depth></size><segmented>0</segmented><object><name>Leconte</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>473</xmin><ymin>578</ymin><xmax>612</xmax><ymax>727</ymax></bndbox></object><object><name>Boerner</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>822</xmin><ymin>505</ymin><xmax>948</xmax><ymax>639</ymax></bndbox></object><object><name>linnaeus</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>607</xmin><ymin>781</ymin><xmax>690</xmax><ymax>842</ymax></bndbox></object><object><name>armandi</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>756</xmin><ymin>786</ymin><xmax>841</xmax><ymax>856</ymax></bndbox></object><object><name>coleoptera</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>624</xmin><ymin>488</ymin><xmax>711</xmax><ymax>554</ymax></bndbox></object>
</annotation>

xml解析讲解

一、标签介绍

上边的示例xml文件中,其中最主要的是filename(文件–图片名称),size(图片大小和通道数), object(就是我们需要关注的目标检测的边界框位置等)。

【再次说明,xml中的标签可以自定义,只需要满足命名规范和标签闭合即可】

  • 标签闭合: <filename> </filename>
    自中,filename就是自定义的标签,前后对账,后者添加一个 /即可
  • 命名规范:
    名称可以包含字母、数字以及其他的字符
    名称不能以数字或者标点符号开始
    名称不能以字母 xml(或者 XML、Xml 等等)开始
    名称不能包含空格

下面就对之前提到的三个部分做简要的说明!

filename标签

<filename>1.jpeg</filename>

这个标签在AI识虫中对应着每一个xml文件对应的图片名称

size标签

<size><width>1344</width><height>1344</height><depth>3</depth>
</size>

可以看出,size中还包含其它的内部标签,此时我们需要解析内部的数据就需要继续继续往里边查找标签——比如对width标签就对应着图片的宽度。【depth:常常表示通道数】

object标签

<object><name>Leconte</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>473</xmin><ymin>578</ymin><xmax>612</xmax><ymax>727</ymax></bndbox>
</object>

object通常就是我们目标检测中检测物体边界框所在的外层标签
其中<difficult>0</difficult>,表示该物体是否检测存在困难;
更重要的是:

<bndbox><xmin>473</xmin><ymin>578</ymin><xmax>612</xmax><ymax>727</ymax>
</bndbox>

bndbox标签中,包含我们检测的边界框的左上顶点(xmin, ymin)右下顶点(xmax, ymax)!

以上,基本上就对一份xml文件内容确定解析标签做了一个基本的阐述。

二、xml解析的API

python中解析xml是通过操做xml库实现的!

  1. 首先导入库: import xml

  2. 具体解析xml文件是使用xml.etrre.ElementTree来构建xml解析树实现的

  3. 该APIxml.etrre.ElementTree下的parse可以快速解析xml文件
    形式如下:
    xml.etrre.ElementTree.parse(xml_path)实现对xml_path对应的xml文件进行解析,并返回一个xml解析树对象!

  4. 此时获取的解析树还只是一个直接的数据,不能直接获取我们想要的东西,此时需要对解析树使用find(标签)来对指定标签进行查讯,并返回该标签对象,然后,再跟上一个text获取该标签的属性(注意:text针对仅含有具体字符数据的标签,如 <fname> 1</fname>, 而不是<img_data><img_name>1</img_name></img_data>这样的复合标签)。
    eg:

# xml解析树
xml_tree = xml.etrre.ElementTree.parse(xml_path)# find从解析对象中找到id标签对象,然后使用text属性,获取xml中该标签对应的数据
id_data = xml_tree.find('id').text # 此时返回的数据是str,如果是数值,可以使用int/float进行转换

总结起来,xml解析最主要的操作就是:

  • 使用xml.etrre.ElementTree.parse(xml_path)创建一个初始的xml树对象;
  • 然后对返回的树对象使用find进行标签查找
  • 找到所需要的子标签时,再使用text属性进行读取即可!

xml单个文件的解析

在解析文件前,我们来确定一下分析xml中所要关注的标签。
在AI识虫的xml中,我们需要关注的标签:

  • filename : 解析出当前xml对应的图片文件名
  • size -> width , height, depth : 解析出图片的大小和通道数
  • objeck -> bndbox : 解析出objeck下的bbox数据
  • difficult : 解析当前bbox是否存在识别困难

接下来就从以上四个方面进行解析——

构建类别索引(category_id)

模型的输出与损失计算都是数值的,而xml中有时候会出现category(类别)名称,需要进行转换!
因此,我们就AI识虫数据集中的xml所存在的类别进行整理:

# 其对应的cotegory有7种
INSECT_NAMES = ['Boerner', 'Leconte', 'Linnaeus', 'acuminatus', 'armandi', 'coleoptera', 'linnaeus']

我们就对以上的类别设置顺序索引,从Boerner-0, Leconte-1, … , linnaeus-6进行映射!
这里利用字典来存取这样的映射,方便我们后边解析出xml中的类别时,可以使用key直接获取类别的id!
构建字典的函数如下:

# 构造类别对应的索引字典
def get_insect_name():"""获取类别索引字典return a dict,{'Boerner': 0,'Leconte': 1,'Linnaeus': 2, 'acuminatus': 3,'armandi': 4,'coleoptera': 5,'linnaeus': 6}"""insect_category2id = {}   # 从类别到id的一个映射for i, item in enumerate(INSECT_NAMES):  # 利用enumerate自带的索引序号进行映射insect_category2id[item] = ireturn insect_category2id

构建xml解析

通过上边的操作,我们就得到了类别映射,后边的的类别名称就可以很方便的解析成id序列号了!
代码具体如下:(所有的重要注释都已经在代码中覆盖了!

# 传入类别索引字典和xml数据地址进行xml解析
# 返回xml中解析到的所有目标数据
def get_annotation(category2id, data_path):'''category2id: 类别索引字典data_path: 数据地址(单个xml的数据的相对地址——1.xml)return records(这是一个list,包含其中返回的字典数据)'''# data_path: 1.xml  => [:-4] = '1'  , [-4:] = '.xml'fid = data_path[:-4]   # id:既是xml的,通常也是img的tree = ET.parse(data_path)objs = tree.findall('object') # 返回所有的object对象(标签)img_w = tree.find('size').find('width').text  # 通过text属性调用xml指定标签的数据img_h = tree.find('size').find('height').text# print('Image Width:', img_w, 'px , Image Height:', img_h, 'px')# 预置我们需要从xml中读取的数据格式——这里的bbox采用xywh的数据格式存储# 根据objs的个数,分配此时解析xml需要多少个bboxgt_bbox = np.zeros((len(objs), 4), dtype=np.float32)  # 4:表示bbox的数据: xywhgt_class = np.zeros((len(objs), 1), dtype=np.int32)   # 1:对应类别索引is_difficult = np.zeros((len(objs), 1), dtype=np.int32) # 1:对应是否识别困难# 预置后数据格式之后,开始遍历objs,依次读取其中的数据,存入到预置的数据格式中for i, obj in enumerate(objs): # 利用enumerate返回自带索引,来方便多个obj的索引和遍历# 类别读取category_name = obj.find('name').text # 获取类别名category_id = category2id[category_name] # 获取对应的类别索引gt_class[i] = category_id  # 添加识别类别索引# 识别是否困难_difficult = int(obj.find('difficult').text) # 获取识别难度is_difficult[i] = _difficult # 读取目标识别是否困难# bbox读取x1 = float(obj.find('bndbox').find('xmin').text)  # 将读取的左上点的x数据转换为float数据y1 = float(obj.find('bndbox').find('ymin').text)x2 = float(obj.find('bndbox').find('xmax').text)  # 右下点y2 = float(obj.find('bndbox').find('ymax').text)# 将读取的bbox数据转换为:xywh的格式存入gt_bbox中bbox_center_x = (x2 + x1) / 2.0bbox_center_y = (y2 + y1) / 2.0bbox_w = (x2 - x1) + 1.0bbox_h = (y2 - y1) + 1.0# 写入gt_bboxgt_bbox[i] = [bbox_center_x, bbox_center_y, bbox_w, bbox_h]  # 这里等价于将gt_bbox[i,:] = [....]# 将当前xml中的所有obj遍历完后,对数据进行一个汇总# 具体实践时的数据解析和汇总可以做适当的调整xml_rcd = {'image_name': fid+'.png',  # 图片名称'image_id': fid,           # 图片id'difficult': is_difficult, # 数据识别困难情况'categoty_id': gt_class,   # 识别对象的类别情况'gt_bbox': gt_bbox         # 识别对象的bbox情况}# 返回解析完归总后的xml内容return xml_rcd

代码测试

# cotegory有7种
INSECT_NAMES = ['Boerner', 'Leconte', 'Linnaeus', 'acuminatus', 'armandi', 'coleoptera', 'linnaeus']# 生成类别索引字典
category2id = get_insect_name()# 返回解析后的xml内容
xml_rcd = get_annotation(category2id=category2id, data_path='1.xml')# 打印解析出来的内容
for key, data in xml_rcd.items():  # 打印返回的内容print(key, ':\n', data)    # 当前数据的内容

打印结果:

到这里,xml的基本解析就介绍完了,如果大家感兴趣,可以在此基础上尝试文件列表中多个xml文件的解析。

目标检测相关教程如下:(更新中)
目标检测(一)——边界框总结与代码实现(可完整实现)
目标检测(二)——锚框总结与代码实现(可完整实现)
目标检测(三)——IoU总结与代码实现(可完整实现)

目标检测(四)——xml快速上手(可完整实现)相关推荐

  1. 目标检测(四):SSD之Pytorch源码解读

    读完 SSD 的论文内容能大致了解这一算法的核心思想和算法流程,但要将其应用到实际问题上还需要去读代码.论文给出的 SSD 源码是用 Caffe 框架实现的,但自己使用 Caffe 搭建 SSD 的环 ...

  2. 全网最最最轻量级检测网络 yolo-fastest 快速上手

    文章目录 0x01 Yolo-Fastest 0x02 Prepare step1 clone step2 make step3 run darknet 0x03 Train step1 获取权重文件 ...

  3. python解析xml+得到pascal voc xml格式用于目标检测+美化xml

    1.python解析xml img_path='./data/001.tif'xml_path='./xml/001.xml'img=cv2.imread(img_path)# cv2.imshow( ...

  4. 目标检测——模型的快速验证

    1 使用训练集来进行评价 通过对训练集来评价,可以了解模型当前的学习程度: 1.1 使用小数据集进行验证--"选择100个样本" 我们可以使用数量较小的数据来进行快速验证,看看模型 ...

  5. 小目标 | Power BI新人快速上手手册

    经常有刚接触Power BI 的朋友询问:该如何上手学习?先学Power Query ,还是 Power Pivot?或者直接学习 Power BI Desktop? 今天,就和大家分享一些我个人的体 ...

  6. 目标检测:XML文件矩形框在图片上的简单可视化

    代码如下: 需要改的就是开头的四行 可视化结果只有框,没有类别 用于验证 自己写的,亲测可用 import xml.etree.ElementTree as ET import os import c ...

  7. 五十四、快速上手uniapp

    @Author:Runsen uniapp可以说是前端必学的东西.uniapp项目可以一套代码运行到多端(APP端(安卓和ios).各种小程序(微信.支付宝.头条.百度.QQ).H5端). 详细介绍请 ...

  8. 目标检测--将xml文件中标签(矩形框)在其原图片上显示并另存

    """ 目的:将原图片(img)与其xml(xml),合成为打标记的图片(labelled),矩形框标记用红色即可 已有:(1)原图片文件夹(imgs_path),(2) ...

  9. 项目设计:基于YOLO目标检测算法的安全帽/口罩/汽车/行人/交通标志...检测

    本文将详细介绍YOLO目标检测算法,该算法支持各种目标检测,包括:安全帽.汽车.造价.交通标志......等.  其他毕业设计题目推荐参考: 毕业设计:电子/通信/计算机/物联网专业毕业设计选题参考( ...

最新文章

  1. centos7 中搭建gitlab
  2. DllMain使用的注意事项
  3. eclipse新建一个java_Eclipse中新建一个java源文件的步骤
  4. Java Review - 并发组件ConcurrentHashMap使用时的注意事项及源码分析
  5. HTML5/CSS3hack
  6. 在ios开发中使用 try 和 catch 来捕获错误。
  7. python onenet_使用Python2.7 POST 数据到 onenet 平台
  8. VMware:为中国中小企业建立“外部云计算”
  9. bucket sort sample sort 并行_IBM布局AI硬件大杀器:硬软件并行开发、开源模拟AI工具包...
  10. python xgboost参数_Python中的XGBoost XGBClassifier默认值
  11. 在家办公怎么弄?华为云DevCloud宝典一看就懂——迭代开发篇
  12. 【SpringMVC】SpringMVC+Spring+hibernate整合
  13. 为informix数据库中的表创建同义词
  14. Spring框架七大核心模块
  15. 怎么设置电脑的固定IP地址?
  16. 搜狗浏览器显示无法解析服务器的DNS地址,搜狗浏览器显示无法解析DNS地址的解决方法...
  17. 经纬度的多种格式和转换方式
  18. 华硕装鸿蒙系统,智能家居 篇八:解决华硕路由器设置不当造成传感器延迟
  19. mysql查看sa密码_sqlserver怎么查看sa密码
  20. @keyframes简单使用

热门文章

  1. java制造业生产管理系统源码
  2. 2022 极术通讯-安谋科技参与起草的PSA相关物联网终端安全标准介绍(电信终端产业协会发布)
  3. 浅谈Java对接阿里IOT
  4. 教你2种常用的电商高并发处理解决方案
  5. 微医在港招股书失效:曾多次喊话上市,注册用户达2.2亿
  6. 关于交换机包转发率1.488Mpps是如何计算出来的?
  7. 一体式计算机内存怎么变大,一体机电脑内存多大合适?
  8. javascript基础知识之三座大山
  9. C语言之指向一维数组的指针
  10. 剪映导出帧率选多少_视频发朋友圈更清晰的四点小技巧