溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

python 批量修改 labelImg 生成的xml文件的方法

發(fā)布時(shí)間:2020-10-26 04:08:12 來(lái)源:腳本之家 閱讀:656 作者:Miscellaneous0712 欄目:開發(fā)技術(shù)

概述

自己在用labelImg打好標(biāo)簽后,想只用其中幾類訓(xùn)練,不想訓(xùn)練全部類別,又不想重新打標(biāo)生成.xml文件,因此想到這個(gè)辦法:直接在.xml文件中刪除原有的不需要的標(biāo)簽類及其屬性。

打標(biāo)時(shí)標(biāo)簽名出現(xiàn)了大小寫(工程量大時(shí)可能會(huì)手滑),程序中有改寫標(biāo)簽值為小寫的過(guò)程,因?yàn)槲易鰌y-faster-rcnn 訓(xùn)練時(shí),標(biāo)簽必須全部為小寫。

以如下的.xml文件為例,我故意把標(biāo)簽增加了大寫

<annotation verified="yes">
 <filename>test.jpg</filename>
 <path>C:\Users\yasin\Desktop\test</path>
 <source>
 <database>Unknown</database>
 </source>
 <size>
 <width>400</width>
 <height>300</height>
 <depth>3</depth>
 </size>
 <segmented>0</segmented>
 <object>
 <name>People</name>
 <pose>Unspecified</pose>
 <truncated>0</truncated>
 <difficult>0</difficult>
 <bndbox>
  <xmin>80</xmin>
  <ymin>69</ymin>
  <xmax>144</xmax>
  <ymax>89</ymax>
 </bndbox>
 </object>
 <object>
 <name>CAT</name>
 <pose>Unspecified</pose>
 <truncated>0</truncated>
 <difficult>0</difficult>
 <bndbox>
  <xmin>40</xmin>
  <ymin>69</ymin>
  <xmax>143</xmax>
  <ymax>16</ymax>
 </bndbox>
 </object>
 <object>
 <name>dog</name>
 <pose>Unspecified</pose>
 <truncated>0</truncated>
 <difficult>0</difficult>
 <bndbox>
  <xmin>96</xmin>
  <ymin>82</ymin>
  <xmax>176</xmax>
  <ymax>87</ymax>
 </bndbox>
 </object> 
</annotation>

具體實(shí)現(xiàn)

假如我們只想保留圖片上的people和cat類,其他都刪除,代碼如下:

from xml.etree.ElementTree import ElementTree
from os import walk, path

def read_xml(in_path):
  tree = ElementTree()
  tree.parse(in_path)
  return tree

def write_xml(tree, out_path):
  tree.write(out_path, encoding="utf-8", xml_declaration=True)

def find_nodes(tree, path):
  return tree.findall(path)

def del_node_by_target_classes(nodelist, target_classes_lower, tree_root):
  for parent_node in nodelist:
    children = parent_node.getchildren()
    if (parent_node.tag == "object" and children[0].text.lower() not in target_classes_lower):
      tree_root.remove(parent_node)
    elif (parent_node.tag == "object" and children[0].text.lower() in target_classes_lower):
      children[0].text = children[0].text.lower()

def get_fileNames(rootdir):
  data_path = []
  prefixs = []
  for root, dirs, files in walk(rootdir, topdown=True):
    for name in files:
      pre, ending = path.splitext(name)
      if ending != ".xml":
        continue
      else:
        data_path.append(path.join(root, name))
        prefixs.append(pre)

  return data_path, prefixs

if __name__ == "__main__":
  # get all the xml paths, prefixes if not used here
  paths_xml, prefixs = get_fileNames("/home/yasin/old_labels/")

  target_classes = ["PEOPLE", "CAT"] # target flags you want to keep

  target_classes_lower = []
  for i in range(len(target_classes)):
    target_classes_lower.append(target_classes[i].lower()) # make sure your target is lowe-case

  # print(target_classes_lower)
  for i in range(len(paths_xml)):
    # rename and save the corresponding xml
    tree = read_xml(paths_xml[i])
    
    # get tree node
    tree_root = tree.getroot()

    # get parent nodes
    del_parent_nodes = find_nodes(tree, "./")
    
    # get target classes and delete
    target_del_node = del_node_by_target_classes(del_parent_nodes, target_classes_lower, tree_root)
    
    # save output xml, 000001.xml
    write_xml(tree, "/home/yasin/new_labels/{}.xml".format("%06d" % i))

按照上述代碼,示例.xml變?yōu)槿缦?xml,可以看出我們刪除了除people和cat類的類別(即dog類),并把保留類別的打標(biāo)改成了小寫:

<?xml version='1.0' encoding='utf-8'?>
<annotation verified="yes">
 <filename>test.jpg</filename>
 <path>C:\Users\yasin\Desktop\test</path>
 <source>
 <database>Unknown</database>
 </source>
 <size>
 <width>400</width>
 <height>300</height>
 <depth>3</depth>
 </size>
 <segmented>0</segmented>
 <object>
 <name>people</name>
 <pose>Unspecified</pose>
 <truncated>0</truncated>
 <difficult>0</difficult>
 <bndbox>
  <xmin>80</xmin>
  <ymin>69</ymin>
  <xmax>144</xmax>
  <ymax>89</ymax>
 </bndbox>
 </object>
 <object>
 <name>cat</name>
 <pose>Unspecified</pose>
 <truncated>0</truncated>
 <difficult>0</difficult>
 <bndbox>
  <xmin>40</xmin>
  <ymin>69</ymin>
  <xmax>143</xmax>
  <ymax>16</ymax>
 </bndbox>
 </object>
</annotation>

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問(wèn)一下細(xì)節(jié)
AI