zoukankan      html  css  js  c++  java
  • 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" + "
    ")
    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)) + "
    ")
    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" + "
    ")
    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)) + "
    ")
    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" + "
    ")
    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)) + "
    ")
    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中,当然还有很多其他的命令语句,以后要有这样的意识,在遇到一个功能的时候,首先想一想是否能用命令或者是脚本的方式进行,这种方法在一开始的时候或许会显得比较慢,因为需要花一些时间去查找相关的命令语句,但是如果用的熟练了之后,就会大大提升效率了。

  • 相关阅读:
    SQL优化大全
    程序的装入和链接
    Linux系统管理常用命令
    作业、进程、线程
    MySQL优化大全
    Linux系统结构 详解
    NoSQL数据库探讨
    操作系统内存管理——分区、页式、段式管理
    进程调度算法
    操作系统文件管理
  • 原文地址:https://www.cnblogs.com/rainsoul/p/6283231.html
Copyright © 2011-2022 走看看