python解析VOC的xml文件並轉成自己需要的txt格式


在進行神經網絡訓練的時候,自己標注的數據集往往會有數據量不夠大以及代表性不強等問題,因此我們會采用開源數據集作為訓練,開源數據集往往具有特定的格式,如果我們想將開源數據集為我們所用的話,就需要對其格式進行解析,然后轉成自己需要的格式,數據轉換的過程其實並沒有太多的技術性的東西,主要涉及的就是文件的讀寫操作以及一點點邏輯,之前都會首選Matlab做這樣的工作,但是開始接觸python之后,嘗試着用python進行,發現也十分簡潔,下面介紹的就是使用python解析VOC2007的xml文件,然后將其中自己需要用到的信息寫到新的txt文件中,以供自己的訓練使用:

 

首先是VOC2007的xml文件格式如下所示,我需要將這樣的xml描述轉成為txt形式的描述文件,並且從中篩選我所需要的幾種格式

 1 <annotation>
 2     <folder>VOC2007</folder>
 3     <filename>000001.jpg</filename>
 4     <source>
 5         <database>The VOC2007 Database</database>
 6         <annotation>PASCAL VOC2007</annotation>
 7         <image>flickr</image>
 8         <flickrid>341012865</flickrid>
 9     </source>
10     <owner>
11         <flickrid>Fried Camels</flickrid>
12         <name>Jinky the Fruit Bat</name>
13     </owner>
14     <size>
15         <width>353</width>
16         <height>500</height>
17         <depth>3</depth>
18     </size>
19     <segmented>0</segmented>
20     <object>
21         <name>dog</name>
22         <pose>Left</pose>
23         <truncated>1</truncated>
24         <difficult>0</difficult>
25         <bndbox>
26             <xmin>48</xmin>
27             <ymin>240</ymin>
28             <xmax>195</xmax>
29             <ymax>371</ymax>
30         </bndbox>
31     </object>
32     <object>
33         <name>person</name>
34         <pose>Left</pose>
35         <truncated>1</truncated>
36         <difficult>0</difficult>
37         <bndbox>
38             <xmin>8</xmin>
39             <ymin>12</ymin>
40             <xmax>352</xmax>
41             <ymax>498</ymax>
42         </bndbox>
43     </object>
44 </annotation>

 

下面就是解析上述xml文件的python腳本,如下所示,主要用到了xml.etree.cElementTree這個包,具體的用法還需要在查一些資料,我就是照着別人的例子先實現了我所需要的功能。下面的代碼首先從一個train.set文件中讀取所有的xml的文件名,然后針對於每一個xml文件,進行解析,並存儲其中我所需要的信息。

 1 #!/usr/bin/evn python 
 2 #coding:utf-8 
 3 import os
 4 
 5 try: 
 6   import xml.etree.cElementTree as ET 
 7 except ImportError: 
 8   import xml.etree.ElementTree as ET 
 9 import sys 
10   
11 file_srx = open("train.set")  #其中包含所有待計算的文件名
12 line = file_srx.readline()
13 while line:
14   f = line[:-1]    # 除去末尾的換行符
15   tree = ET.parse(f)     #打開xml文檔 
16   root = tree.getroot()         #獲得root節點  
17   print "*"*10
18   filename = root.find('filename').text
19   filename = filename[:-4]
20   print filename 
21   #file_object = open(filename + ".txt", 'w') #寫文件
22   file_object_log = open(filename + ".log", 'w') #寫文件
23   flag = False
24   
25   ########################################
26   for size in root.findall('size'): #找到root節點下的size節點 
27     width = size.find('width').text   #子節點下節點width的值 
28     height = size.find('height').text   #子節點下節點height的值 
29     print width, height
30   ########################################
31   
32   for object in root.findall('object'): #找到root節點下的所有object節點 
33     name = object.find('name').text   #子節點下節點name的值 
34     print name
35     bndbox = object.find('bndbox')      #子節點下屬性bndbox的值 
36     xmin = bndbox.find('xmin').text
37     ymin = bndbox.find('ymin').text
38     xmax = bndbox.find('xmax').text
39     ymax = bndbox.find('ymax').text
40     print xmin, ymin, xmax, ymax
41     if name == ("bicycle" or "motorbike"):
42       #file_object.write("Cyclist" + " 0 0 0 " + xmin + ".00 " + ymin + ".00 " + xmax + ".00 " + ymax + ".00 " + "0 0 0 0 0 0 0" + "\n")
43       file_object_log.write(str(float(int(xmax) - int(xmin)) * 1920.0 / float(width)) + " " + str(float(int(ymax) - int(ymin)) * 1080.0 / float(height)) + "\n")
44       flag = True
45     if name == ("car"):
46       #file_object.write("Car" + " 0 0 0 " + xmin + ".00 " + ymin + ".00 " + xmax + ".00 " + ymax + ".00 " + "0 0 0 0 0 0 0" + "\n")
47       file_object_log.write(str(float(int(xmax) - int(xmin)) * 1920.0 / float(width)) + " " + str(float(int(ymax) - int(ymin)) * 1080.0 / float(height)) + "\n")
48       flag = True
49     if name == ("person"):
50       #file_object.write("Pedestrian" + " 0 0 0 " + xmin + ".00 " + ymin + ".00 " + xmax + ".00 " + ymax + ".00 " + "0 0 0 0 0 0 0" + "\n")
51       file_object_log.write(str(float(int(xmax) - int(xmin)) * 1920.0 / float(width)) + " " + str(float(int(ymax) - int(ymin)) * 1080.0 / float(height)) + "\n")
52       flag = True
53   #file_object.close( )
54   file_object_log.close()
55   if flag == False:  #如果沒有符合條件的信息,則刪掉相應的txt文件以及jpg文件
56     #os.remove(filename + ".txt")
57     #os.remove(filename + ".jpg")
58     os.remove(filename + ".log")
59   line = file_srx.readline() 

 

另外,由於使用windows系統習慣了,很多操作都是采取鼠標加鍵盤進行的,比如剪切+粘貼等,這些操作在文件較少的時候是十分方便的,但是當需要對大批文件進行操作的時候就沒有那么方便了,比如要對上萬個文件進行剪切的時候,光是選文件就要拖拽好久,而且一不小心就得重來,在這種情況下,采取dos的批處理操作就十分方便了,比如移動文件的操作(也就是剪切粘貼)只需要一個命令:move*.jpg jpg\則將當前目錄下的所有后綴為jpg的文件都移動到了當前目錄的下級目錄jpg中,當然還有很多其他的命令語句,以后要有這樣的意識,在遇到一個功能的時候,首先想一想是否能用命令或者是腳本的方式進行,這種方法在一開始的時候或許會顯得比較慢,因為需要花一些時間去查找相關的命令語句,但是如果用的熟練了之后,就會大大提升效率了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM