python Pascal VOC の Annotationデータ(XML)を解析する
Pascal VOCのAnnotationデータから必要な情報を抜き出したときの備忘録
作業内容
- サンプルデータより以下のデータを取得する
<filename>
のtextを取得する<size>
の<width>
と<height>
のtextを取得する<object>
の<name>
のtextが"person"の場合のみ<bndbox>
の各tagのtextを取得する
目次
サンプルデータ
- 000001.xml
<annotation> <folder>VOC2007</folder> <filename>000001.jpg</filename> <source> <database>The VOC2007 Database</database> <annotation>PASCAL VOC2007</annotation> <image>flickr</image> <flickrid>341012865</flickrid> </source> <owner> <flickrid>Fried Camels</flickrid> <name>Jinky the Fruit Bat</name> </owner> <size> <width>353</width> <height>500</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>dog</name> <pose>Left</pose> <truncated>1</truncated> <difficult>0</difficult> <bndbox> <xmin>48</xmin> <ymin>240</ymin> <xmax>195</xmax> <ymax>371</ymax> </bndbox> </object> <object> <name>person</name> <pose>Left</pose> <truncated>1</truncated> <difficult>0</difficult> <bndbox> <xmin>8</xmin> <ymin>12</ymin> <xmax>352</xmax> <ymax>498</ymax> </bndbox> </object> </annotation>
xml解析の方法
- xml.etree.ElementTreeをimportする
- parseでxmlファイルを解析する
- getroot()で解析結果を取得する
#! /usr/bin/python3 import xml.etree.ElementTree as ET # XMLファイルを解析 tree = ET.parse('000001.xml') # 解析結果を取得 annotation = tree.getroot()
xmlファイルを見て配列で要素へアクセスする
- annotationの子ノードにfilename、size、objectがある
- filenameは1番目、sizeは4番目、objectは6番目以降である
- sizeのheightの要素にアクセスしたいならばannotation[4][1].textでOK。
# textを取得 filename = annotation[1].text size = [annotation[4][0].text, annotation[4][1].text] bndboxs = [] for i in range(6,len(annotation)): obj_names = annotation[i][0] bndbox_tags = annotation[i][4] if obj_names.text == "person": bndbox = [bndbox_tags[n].text for n in range(4)] bndboxs.append(bndbox) print(filename) print(size) print(bndboxs)
000001.jpg ['353', '500'] [['8', '12', '352', '498']]
tagを検索する方法
主な使い方だけ記載。配列でアクセスするほうがやりやすかったので・・・
- find() : 最初の子ノードを検索
# find() : 最初の子ノードを検索 filename = annotation.find('filename').text ## 最初の子要素ではないのでエラーになる width = annotation.find('width').text
- findall() : 子要素をListで返す
for objects in annotation.findall('object'): obj_name = objects.find('name').text print(obj_name)
dog person
- iter() : 現在の要素とそれ以下のすべての要素を、文書内での出現順 (深さ優先順) でイテレートする
# すべてのタグを表示 for itr in annotation.iter('*'): print(itr.tag) # 深い階層のtextを表示 for w in annotation.iter('width'): print(w.text)
以上