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中的列表推导浅析
Apr 26 Python
Python实现类继承实例
Jul 04 Python
python九九乘法表的实例
Sep 26 Python
Python2/3中urllib库的一些常见用法
Dec 19 Python
python读取文本中的坐标方法
Oct 14 Python
PyCharm在新窗口打开项目的方法
Jan 17 Python
Tensorflow 多线程与多进程数据加载实例
Feb 05 Python
python GUI库图形界面开发之PyQt5 Qt Designer工具(Qt设计师)详细使用方法及Designer ui文件转py文件方法
Feb 26 Python
python else语句在循环中的运用详解
Jul 06 Python
Python 使用生成器代替线程的方法
Aug 04 Python
如何利用python 读取配置文件
Jan 06 Python
Python绘制散乱的点构成的图的方法
Apr 21 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
深入理解curl类,可用于模拟get,post和curl下载
2013/06/08 PHP
ThinkPHP自定义函数解决模板标签加减运算的方法
2015/07/03 PHP
46 个非常有用的 PHP 代码片段
2016/02/16 PHP
php版银联支付接口开发简明教程
2016/10/14 PHP
PHP 实现公历日期与农历日期的互转换
2017/09/13 PHP
PHP实现APP微信支付的实例讲解
2018/02/10 PHP
Jquery插件之Fancybox丰富的弹出层效果附源码下载
2015/12/02 Javascript
浏览器检测JS代码(兼容目前各大主流浏览器)
2016/02/21 Javascript
基于Bootstrap实现Material Design风格表单插件 附源码下载
2016/04/18 Javascript
KnockoutJS 3.X API 第四章之数据控制流foreach绑定
2016/10/10 Javascript
Angular的自定义指令以及实例
2016/12/26 Javascript
微信小程序页面间通信的5种方式
2017/03/31 Javascript
Vue.js鼠标悬浮更换图片功能
2017/05/17 Javascript
Angular 4根据组件名称动态创建出组件的方法教程
2017/11/01 Javascript
Bootstrap-table自定义可编辑每页显示记录数
2018/09/07 Javascript
webpack4实现不同的导出类型
2019/04/09 Javascript
一些手写JavaScript常用的函数汇总
2019/04/16 Javascript
简单了解微信小程序 e.target与e.currentTarget的不同
2019/09/27 Javascript
JavaScript实现随机五位数验证码
2019/09/27 Javascript
[04:37]DOTA2英雄梦之声Vol20发条
2014/06/20 DOTA
[02:40]2018年度DOTA2最佳新人-完美盛典
2018/12/16 DOTA
[43:53]OG vs EG 2019国际邀请赛淘汰赛 胜者组 BO3 第三场 8.22
2019/09/05 DOTA
python 对象和json互相转换方法
2018/03/22 Python
python3安装speech语音模块的方法
2018/12/24 Python
判断python对象是否可调用的三种方式及其区别详解
2019/01/31 Python
PyQt QListWidget修改列表项item的行高方法
2019/06/20 Python
Python socket处理client连接过程解析
2020/03/18 Python
canvas线条的属性详解
2018/03/27 HTML / CSS
华润集团网上药店:健一网
2016/09/19 全球购物
Pretty Green美国:英式摇滚服饰风格代表品牌之一
2019/01/23 全球购物
擅自离岗检讨书
2014/09/12 职场文书
2014年流动人口工作总结
2014/11/26 职场文书
2015年世界水日活动总结
2015/02/09 职场文书
比赛主持人开场白
2015/05/29 职场文书
ORACLE查看当前账号的相关信息
2021/06/18 Oracle
星际争霸 Light vs Action 一场把教主看到鬼畜的比赛
2022/04/01 星际争霸