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


Posted in Python onSeptember 09, 2019

概述

自己在用labelImg打好标签后,想只用其中几类训练,不想训练全部类别,又不想重新打标生成.xml文件,因此想到这个办法:直接在.xml文件中删除原有的不需要的标签类及其属性。

打标时标签名出现了大小写(工程量大时可能会手滑),程序中有改写标签值为小写的过程,因为我做py-faster-rcnn 训练时,标签必须全部为小写。

以如下的.xml文件为例,我故意把标签增加了大写

<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>

具体实现

假如我们只想保留图片上的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变为如下.xml,可以看出我们删除了除people和cat类的类别(即dog类),并把保留类别的打标改成了小写:

<?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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python导入txt数据到mysql的方法
Apr 08 Python
讲解Python中运算符使用时的优先级
May 14 Python
python计算圆周率pi的方法
Jul 11 Python
在Django框架中设置语言偏好的教程
Jul 27 Python
Python3 Random模块代码详解
Dec 04 Python
Python实现Dijkstra算法
Oct 17 Python
搭建python django虚拟环境完整步骤详解
Jul 08 Python
python通过实例讲解反射机制
Oct 17 Python
django框架cookie和session用法实例详解
Dec 10 Python
Python2与Python3的区别详解
Feb 09 Python
python matplotlib:plt.scatter() 大小和颜色参数详解
Apr 14 Python
Python 删除List元素的三种方法remove、pop、del
Nov 16 Python
Python定时发送天气预报邮件代码实例
Sep 09 #Python
python英语单词测试小程序代码实例
Sep 09 #Python
Python实现TCP通信的示例代码
Sep 09 #Python
Python3使用PySynth制作音乐的方法
Sep 09 #Python
python智联招聘爬虫并导入到excel代码实例
Sep 09 #Python
python 的 openpyxl模块 读取 Excel文件的方法
Sep 09 #Python
pymysql模块的使用(增删改查)详解
Sep 09 #Python
You might like
PHP 中的一些经验积累
2006/10/09 PHP
php addslashes和mysql_real_escape_string
2010/01/24 PHP
jquery UI 1.72 之datepicker
2009/12/29 Javascript
Javascript中的相等与不等运算
2010/04/25 Javascript
javascript中的nextSibling使用陷(da)阱(keng)
2014/05/05 Javascript
sogou地图API用法实例教程
2014/09/11 Javascript
Javascript 拖拽雏形(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
JS获取Table中td值的方法
2015/03/19 Javascript
jquery dataview数据视图插件使用方法
2016/12/23 Javascript
微信禁止下拉查看URL的处理方法
2017/09/28 Javascript
Vue组件通信的四种方式汇总
2018/02/08 Javascript
搭建element-ui的Vue前端工程操作实例
2018/02/23 Javascript
Vue 重置组件到初始状态的方法示例
2018/10/10 Javascript
nodejs基础之常用工具模块util用法分析
2018/12/26 NodeJs
React性能优化系列之减少props改变的实现方法
2019/01/17 Javascript
VUE接入腾讯验证码功能(滑块验证)备忘
2019/05/07 Javascript
jquery实现两个div中的元素相互拖动的方法分析
2020/04/05 jQuery
python中关于时间和日期函数的常用计算总结(time和datatime)
2013/03/08 Python
搭建Python的Django框架环境并建立和运行第一个App的教程
2016/07/02 Python
Python生成器定义与简单用法实例分析
2018/04/30 Python
Python网络爬虫之爬取微博热搜
2019/04/18 Python
Python读取xlsx文件的实现方法
2019/07/04 Python
在pytorch中对非叶节点的变量计算梯度实例
2020/01/10 Python
税务专业毕业生自荐信
2013/11/10 职场文书
迎新晚会策划方案
2014/06/13 职场文书
领导干部查摆“四风”问题自我剖析材料思想汇报
2014/10/05 职场文书
社保缴纳证明申请书
2014/11/03 职场文书
2015年业务员工作总结范文
2015/04/07 职场文书
商标侵权律师函
2015/05/27 职场文书
贷款工作证明模板
2015/06/12 职场文书
2016春节放假通知范文
2015/08/18 职场文书
MySQL数据迁移相关总结
2021/04/29 MySQL
从QQtabBar看css命名规范BEM的详细介绍
2021/08/07 HTML / CSS
详解Python中__new__方法的作用
2022/03/31 Python
如何优化vue打包文件过大
2022/04/13 Vue.js
纯CSS打字动画的实现示例
2022/08/05 HTML / CSS