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使用Socket(Https)Post登录百度的实现代码
May 18 Python
Python的语言类型(详解)
Jun 24 Python
Python定时任务sched模块用法示例
Jul 16 Python
Python绘制的二项分布概率图示例
Aug 22 Python
django利用request id便于定位及给日志加上request_id
Aug 26 Python
python 划分数据集为训练集和测试集的方法
Dec 11 Python
详解python校验SQL脚本命名规则
Mar 22 Python
python sorted方法和列表使用解析
Nov 18 Python
浅析Python数字类型和字符串类型的内置方法
Dec 22 Python
信号生成及DFT的python实现方式
Feb 25 Python
Python with语句用法原理详解
Jul 03 Python
python 命令行传参方法总结
May 25 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中session_id()函数详细介绍,会话id生成过程及session id长度
2015/09/23 PHP
php文件后缀不强制为.php的实操方法
2019/09/18 PHP
JavaScript入门教程(5) js Screen屏幕对象
2009/01/31 Javascript
mysql输出数据赋给js变量报unterminated string literal错误原因
2010/05/22 Javascript
jquery实现在页面加载的时自动为日期插件添加当前日期
2014/08/20 Javascript
深入理解JavaScript的React框架的原理
2015/07/02 Javascript
JS特效实现图片自动播放并可控的效果
2015/07/31 Javascript
js点击列表文字对应该行显示背景颜色的实现代码
2015/08/05 Javascript
JavaScript中的Number数字类型学习笔记
2016/05/26 Javascript
a标签跳转到指定div,jquery添加和移除class属性的实现方法
2016/10/10 Javascript
js遮罩效果制作弹出注册界面效果
2017/01/25 Javascript
纯js实现动态时间显示
2020/09/07 Javascript
AngularJS service之select下拉菜单效果
2017/07/28 Javascript
微信小程序多列选择器range-key使用详解
2020/03/30 Javascript
浅谈Vuejs中nextTick()异步更新队列源码解析
2017/12/31 Javascript
Vue.set()实现数据动态响应的方法
2018/02/07 Javascript
详解如何webpack使用DllPlugin
2018/09/30 Javascript
vue cli 3.x 项目部署到 github pages的方法
2019/04/17 Javascript
js实现弹窗效果
2020/08/09 Javascript
[36:22]VP vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
利用python实现数据分析
2017/01/11 Python
Django 使用logging打印日志的实例
2018/04/28 Python
pandas计数 value_counts()的使用
2019/06/24 Python
Python3实现将一维数组按标准长度分隔为二维数组
2019/11/29 Python
浅谈SciPy中的optimize.minimize实现受限优化问题
2020/02/29 Python
Python3 Tensorlfow:增加或者减小矩阵维度的实现
2020/05/22 Python
基于python和flask实现http接口过程解析
2020/06/15 Python
numpy中生成随机数的几种常用函数(小结)
2020/08/18 Python
python装饰器三种装饰模式的简单分析
2020/09/04 Python
CSS3的column-fill属性对齐列内容高度的用法详解
2016/07/01 HTML / CSS
JBL英国官网:JBL UK
2018/07/04 全球购物
机械工程系毕业生求职信
2013/09/27 职场文书
海洋科学专业求职信
2014/08/10 职场文书
新兵入伍决心书
2015/09/22 职场文书
《将心比心》教学反思
2016/02/23 职场文书
职场中的你,辞职信写对了吗?
2019/06/26 职场文书