本文主要记录下自己将xml文件中有用的数据提取至txt的过程。在查找代码时发现,大都复制粘贴的代码,不仅冗余,而且晦涩难懂,于是自己整理了一套代码。不多说,直接图解。
大家的xml文件大同小异,可以耐心看完,自己就会改了。
<annotation>
<folder>UAV_datafolder>
<filename>anju _19.jpgfilename>
<source>
<database>The UAV autolandingdatabase>
<annotation>UAV AutoLandingannotation>
<image>flickrimage>
<flickrid>NULLflickrid>
source>
<owner>
<flickrid>NULLflickrid>
<name>ChaojieZhuname>
owner>
<size>
<width>1080width>
<height>1080height>
<depth>3depth>
size>
<segmented>0segmented>
<object>
<name>parksetname>
<pose>Unspecifiedpose>
<truncated>1truncated>
<difficult>0difficult>
<bndbox>
<xmin>0.0xmin>
<ymin>422.0ymin>
<xmax>347.1904761904762xmax>
<ymax>626.0ymax>
bndbox>
<keypoints>
<x0>323.0x0>
<y0>626.0y0>
<x1>347.1904761904762x1>
<y1>463.4920634920635y1>
<x2>0.0x2>
<y2>422.0y2>
<x3>0.0x3>
<y3>589.0y3>
keypoints>
object>
<object>
<name>wheel_stoppername>
<pose>Unspecifiedpose>
<truncated>1truncated>
<difficult>0difficult>
<bndbox>
<xmin>782.0408163265306xmin>
<ymin>514.2857142857142ymin>
<xmax>986.937984496124xmax>
<ymax>658.1395348837209ymax>
bndbox>
<keypoints>
<x0>793.0612244897959x0>
<y0>514.2857142857142y0>
<x1>782.0408163265306x1>
<y1>645.3061224489795y1>
<x2>976.8604651162791x2>
<y2>658.1395348837209y2>
<x3>986.937984496124x3>
<y3>537.2093023255813y3>
keypoints>
object>
<object>
<name>wheel_stoppername>
<pose>Unspecifiedpose>
<truncated>1truncated>
<difficult>0difficult>
<bndbox>
<xmin>765.8959537572255xmin>
<ymin>660.1156069364162ymin>
<xmax>977.4193548387096xmax>
<ymax>812.9032258064516ymax>
bndbox>
<keypoints>
<x0>780.9248554913295x0>
<y0>660.1156069364162y0>
<x1>765.8959537572255x1>
<y1>795.9537572254335y1>
<x2>954.8387096774193x2>
<y2>812.9032258064516y2>
<x3>977.4193548387096x3>
<y3>673.5483870967741y3>
keypoints>
object>
<object>
<name>wheel_stoppername>
<pose>Unspecifiedpose>
<truncated>1truncated>
<difficult>0difficult>
<bndbox>
<xmin>9.418604651162795xmin>
<ymin>437.2093023255814ymin>
<xmax>66.21621621621621xmax>
<ymax>483.3333333333333ymax>
bndbox>
<keypoints>
<x0>62.61261261261261x0>
<y0>483.3333333333333y0>
<x1>66.21621621621621x1>
<y1>442.79279279279274y1>
<x2>11.74418604651163x2>
<y2>437.2093023255814y2>
<x3>9.418604651162795x3>
<y3>472.09302325581393y3>
keypoints>
我是想得到 filename 中的anju_19.jpg以及 keypoints中x0 y0 x1 y1这些数据点,并在txt中间断空格保存。那么问题来了,如何解析呢,下面付了代码并做出了解释。
我知道你最想要的是代码,那么代码如下,。。。。
等等确定不看下 下面解释来理解一下原理嘛。 保你看懂哦,看懂看到任何xml转格式和提取再也不怕啦。
#from os import listdir, getcwd
#from os.path import join
import cv2
import os
from xml.etree.ElementTree import parse
xmlfilepath='D:\\destop\\dst\\xml\\' #你的xml文件夹路径,不是xml文件,批量处理时用
total_xml = os.listdir(xmlfilepath)#遍历xml文件
for xml in total_xml:
xml_path=os.path.join(xmlfilepath,xml)#xml的全路径,也就是文件的路径
print(xml_path)
tree = parse(xml_path) #获取ElementTree
root = tree.getroot() #获取根元素
filename = root.findtext('filename')#提取到了xml对应的 filename的名字
print('filename:',filename)
for obj in root.iter('object'):#看上面xml文件可知我想要的keypoints在object这个标签下,而且有很多object ,因此我要遍历object
print('obj:',str(obj))
cls = obj.find('name').text#将解析得到该keypoints下 name中的标签,也就是wheel_stopper类
print('cls:',cls)
if cls=='wheel_stopper': #由与还有标签parkset类 而我只想要wheel_stopper类别下的x0 y0....
xmlbox = obj.find('keypoints') #此时得到了想要的点x0,y0,x1,y1,
b = ((xmlbox.find('x0').text), (xmlbox.find('y0').text),
( xmlbox.find('x1').text), (xmlbox.find('y1').text))
with open('D:\\destop\\dst\\1.txt','a') as f:#不用创建,自己存一个路径 我这里是1.txt 那你呢。。你定吧
f.write(str(filename))
print("b:",b[0])
for i in range(len(b)):
f.write(' ')
f.write(str(b[i]))
f.write('\n')
重要的要理解
root = tree.getroot() #获取根元素
filename = root.findtext('filename')#提取到了xml对应的 filename的名字
上述代码root就是将xml加载解析了,而filename(上图红色箭头指向)相当于一级目录,这个一级目录下就他自己,用root.findtext(‘filename’)即可解析得到。
暂且通俗易懂的叫object为一级目录,想得到的x0,y0,x1,y1在object下的keypoints中,
这相当于keypoints是二级目录,如果想要得到Xmin Ymin就将 keypoints换为bndbox即可。
看上图蓝色箭头知道object不止一个呀,咋办哦, 那就遍历所有object,于是下面代码相当于遍历了一遍一级目录 ‘object’,于是可以可以得到二级目录运用obj.find(‘name’)这里name可以替换成任意二级目录。
敲黑板啦,你的name应该是你要的类别,你的name可能不是我的wheel_stopper,可能是car ,person,dog等一些类别标签,注意替换哦。这里我只想要wheel_stopper,所以你想要啥标签可以自己写下,也可以找我帮你嘛
for obj in root.iter('object'):#看上面xml文件可知我想要的keypoints在object这个标签下,而且有很多object ,因此我要遍历object
print('obj:',str(obj))
cls = obj.find('name').text#将解析得到该keypoints下 name中的标签,也就是wheel_stopper类
print('cls:',cls)
if cls=='wheel_stopper': #由与还有标签parkset类 而我只想要wheel_stopper类别下的x0 y0....
xmlbox = obj.find('keypoints') #此时得到了想要的点x0,y0,x1,y1,
b = ((xmlbox.find('x0').text), (xmlbox.find('y0').text),
( xmlbox.find('x1').text), (xmlbox.find('y1').text))
运用 xmlbox = obj.find(‘keypoints’) #此时得到了想要的点x0,y0,x1,y1,
运用xmlbox.find(‘x0’).text),就可以得到X0数据,以此类推。
with open('D:\\destop\\dst\\1.txt','a') as f:#不用创建,自己存一个路径 我这里是1.txt 那你呢。。你定吧
这里的目的是创建一个txt存取 提取的x0,y0等
最终得到了数据如下图:
我这个文件夹就有一个xml文件 所以只有一个名字,并且没有将数据写在一行,你可以更改的哦,我后面需要的时候更改啦
怎么样,不知道讲清楚了没。
如果对你有帮助,还希望一键三连啊。
欢迎被代码困住的 被debug缠身的小伙伴交流解决,视觉相关代码,单目测距,论文撰写,(yolo,presacn,matlab,c++)皆可交流哦------------------------!