XML(eXtensible Markup Language)指可擴充标記語言,被設計用來傳輸和存儲資料,已經日趨成為目前許多新生技術的核心,在不同的領域都有着不同的應用。它是web發展到一定階段的必然産物,既具有SGML的核心特征,又有着HTML的簡單特性,還具有明确和結構良好等許多新的特性。
在做目标檢測手工标注資料集的時候,通常會把标注的目标位置資訊寫入一個.xml檔案,但在檢查資料和資料清洗的時候,面對一堆坐标資料很難對标注的準确性進行檢查,是以通常需要對xml檔案進行解析,讀出其中儲存的目标和目标的一些資訊。
需要解析的xml檔案如下
<annotation>
<folder>Images</folder>
<filename>00001</filename>
<path>E:\Images\00001.jpg</path>
<source>
<database>Unknown</database>
</source>
<size>
<width>432</width>
<height>495</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>mirror</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>3</xmin>
<ymin>159</ymin>
<xmax>52</xmax>
<ymax>202</ymax>
</bndbox>
</object>
<object>
<name>mirror</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>370</xmin>
<ymin>134</ymin>
<xmax>427</xmax>
<ymax>179</ymax>
</bndbox>
</object>
<object>
<name>glass</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>56</xmin>
<ymin>102</ymin>
<xmax>373</xmax>
<ymax>224</ymax>
</bndbox>
</object>
<object>
<name>light</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>29</xmin>
<ymin>325</ymin>
<xmax>114</xmax>
<ymax>389</ymax>
</bndbox>
</object>
<object>
<name>light</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>322</xmin>
<ymin>305</ymin>
<xmax>405</xmax>
<ymax>372</ymax>
</bndbox>
</object>
</annotation>
Ok ,從結構上,它很像我們常見的HTML超文本标記語言。但他們被設計的目的是不同的,超文本标記語言被設計用來顯示資料,其焦點是資料的外觀。它被設計用來傳輸和存儲資料,其焦點是資料的内容。
那麼它有如下特征:
首先,它是有标簽對組成:
<aa></aa>
标簽可以有屬性:
<aa id=’123’></aa>
标簽對可以嵌入資料:
<aa>abc</aa>
标簽可以嵌入子标簽(具有層級關系):
<aa>
<bb></bb>
</aa>
上面的xml檔案儲存了目标的名字:name和四個坐标(xmin, ymin, xmax, ymax),使用python對其進行解析。
#coding=utf-8
import xml.dom.minidom
#打開xml文檔
dom = xml.dom.minidom.parse('abc.xml')
#得到文檔元素對象
root = dom.documentElement
print root.nodeName
print root.nodeValue
print root.nodeType
print root.ELEMENT_NODE
mxl.dom.minidom 子產品被用來處理xml檔案,是以要先引入。
xml.dom.minidom.parse() 用于打開一個xml檔案,并将這個檔案對象dom變量。
documentElement 用于得到dom對象的文檔元素,并把獲得的對象給root
每一個結點都有它的nodeName,nodeValue,nodeType屬性。
nodeName為結點名字。
nodeValue是結點的值,隻對文本結點有效。
nodeType是結點的類型。catalog是ELEMENT_NODE類型
現在有以下幾種:
‘ATTRIBUTE_NODE’
‘CDATA_SECTION_NODE’
‘COMMENT_NODE’
‘DOCUMENT_FRAGMENT_NODE’
‘DOCUMENT_NODE’
‘DOCUMENT_TYPE_NODE’
‘ELEMENT_NODE’
‘ENTITY_NODE’
‘ENTITY_REFERENCE_NODE’
‘NOTATION_NODE’
‘PROCESSING_INSTRUCTION_NODE’
‘TEXT_NODE’
NodeTypes - 有名常數
對于上文列出的xml檔案,筆者使用了如下腳本,供讀者進行參考,可根據自己的需要修改。
#! /usr/bin/env python
#coding = utf-8
from xml.dom.minidom import parse
import xml.dom.minidom
from PIL import Image, ImageDraw
import os
import ImageFont
xml_path = '/Users/Lee/Desktop/check_xml/experiments/xml/'
filelists = os.listdir(xml_path)
filelists.pop()
img_path = '/Users/Lee/Desktop/check_xml/experiments/images/'
save_path = '/Users/Lee/Desktop/check_xml/experiments/check_img/'
num =
for file in filelists:
xml_file_path = os.path.join(xml_path+file)
DOMTree = xml.dom.minidom.parse(xml_file_path)
Data = DOMTree.documentElement
img_name_tmp = Data.getElementsByTagName("filename")
img_name = img_name_tmp[].childNodes[].data
Objects = Data.getElementsByTagName("object")
xmin_1 = []
ymin_1 = []
xmax_1 = []
ymax_1 = []
name_1 = []
for object in Objects:
name = object.getElementsByTagName('name')[]
name_1.append(name.childNodes[].data)
xmin = object.getElementsByTagName('xmin')[]
xmin_1.append(int(xmin.childNodes[].data))
ymin = object.getElementsByTagName('ymin')[]
ymin_1.append(int(ymin.childNodes[].data))
xmax = object.getElementsByTagName('xmax')[]
xmax_1.append(int(xmax.childNodes[].data))
ymax = object.getElementsByTagName('ymax')[]
ymax_1.append(int(ymax.childNodes[].data))
img = Image.open(os.path.join(img_path+img_name+'.jpg'))
num_object = len(name_1)
for i in range(num_object):
x_text = (xmax_1[i] - xmin_1[i]) * + xmin_1[i]
y_text = ymin_1[i] -
draw_name = ImageDraw.Draw(img)
font1 = ImageFont.truetype("times_New_Roman.ttf",)
draw_name.text((x_text, y_text), name_1[i], fill= (,,), font = font1)
draw_rect = ImageDraw.Draw(img)
draw_rect.rectangle([(xmin_1[i], ymin_1[i]), (xmax_1[i], ymax_1[i])],outline=(,,))
img.save(os.path.join(save_path + img_name + '.jpg'))
num = num +
if num % == :
print num
上述腳本可以把xml儲存的名字和位置資訊在原圖上反映出來,用以檢查手工标注資料的準确性。