python ndarray合并label_荐合并使用labelimg标注的同一张图片的两个不同xml标签

待解决问题

对于某个文件夹下的所有图片,使用labelimg进行标注,获得voc类型的xml格式的标签。由于在进行标注工作时,将不同的类别分开标注了,得到标签文件夹有两个,第一个文件夹存储了类别 a 和类别 b 的 labels ,第二个文件夹存储了类别 c, d, e… 的 labels 。现在想要将相同图片的标签进行,即原本一张图片可能有两个对应的 xml,现在要使得一张图片只有一个对应的 xml。

目标效果

原图:

标签1

标签2

标签合并

解决思路

通过分析 xml 文件,得知关键的标签信息存在于 xml 中的 object节点中,那么只要将相同图片的两个 xml 文件中的object进行拼接即可。

解决方案

例如:

xml1:

images

1_191.jpg

/home/shan/Desktop/VOC/images/1_191.jpg

Unknown

1920

1080

3

0

no

Unspecified

0

0

240

37

290

79

no

Unspecified

0

0

401

23

460

65

xml2:

xu

1_191.jpg

/home/aibc/Desktop/xu/1_191.jpg

Unknown

1920

1080

3

0

excavator arm

Unspecified

0

0

938

38

1063

116

person

Unspecified

1

0

1037

1

1047

28

xml1 和 xml2 都是 图片1_191.jpg 的标签,我们现在将它们合并。

先了解一些 xml 基本操作

读取

读取文档:tree = ET.parse()

获得根节点:root = tree.getroot()

获得所有子节点:list()

查找子节点,注意这里不会递归查找所有子节点:root.findall('object')

查找子节点,递归查找所有子节点:root.iter()

查看节点名称:root.tag

写入

创建节点:root = ET.Element)

创建文档:tree = ET.ElementTree()

设置文本值:element.text

设置属性:element.set()

添加节点:root.append()

写入文档:tree.write()

代码奉上

单张图片

from xml.etree.ElementTree import ElementTree, Element, parse

import xml.etree.ElementTree as ET

# 缩进对齐

def __indent(elem, level=0):

i = "\n" + level*"\t"

if len(elem):

if not elem.text or not elem.text.strip():

elem.text = i + "\t"

if not elem.tail or not elem.tail.strip():

elem.tail = i

for elem in elem:

__indent(elem, level+1)

if not elem.tail or not elem.tail.strip():

elem.tail = i

else:

if level and (not elem.tail or not elem.tail.strip()):

elem.tail = i

# 读取xml1文件

# 为了方便演示,我将两个 1_191.xml 分别手动重命名为 1_191_1.xml 和 1_191_2.xml

tree_1 = parse('1_191_1.xml')

root_1 = tree_1.getroot() # annotation

new_1 = tree_1

# 读取xml2文件

tree_2 = parse('1_191_2.xml')

root_2 = tree_2.getroot() # annotation

# 找到所有object节点

object = (tree_2.findall('object'))

length = len(object)

# 将tree_2中的所有object节点加入到root_1中

for i in range(length):

root_1.append(object[i])

__indent(root_1)

new_1.write('./1_191.xml')

得到的输出结果为:

images

1_191.jpg

/home/shan/Desktop/VOC/images/1_191.jpg

Unknown

1920

1080

3

0

no

Unspecified

0

0

240

37

290

79

no

Unspecified

0

0

401

23

460

65

excavator arm

Unspecified

0

0

938

38

1063

116

person

Unspecified

1

0

1037

1

1047

28

可以看到,问题解决_

批量操作

from xml.etree.ElementTree import ElementTree, Element, parse

import xml.etree.ElementTree as ET

import os

import shutil

hole_path = './Annotations'

arm_path = './Anno'

out_path = './Fusing'

# 格式化

def __indent(elem, level=0):

i = "\n" + level*"\t"

if len(elem):

if not elem.text or not elem.text.strip():

elem.text = i + "\t"

if not elem.tail or not elem.tail.strip():

elem.tail = i

for elem in elem:

__indent(elem, level+1)

if not elem.tail or not elem.tail.strip():

elem.tail = i

else:

if level and (not elem.tail or not elem.tail.strip()):

elem.tail = i

for hole_xml in os.listdir(hole_path):

# 将同名xml合并

if os.path.exists(os.path.join(arm_path,hole_xml)):

print('fusing',hole_xml)

tree_hole = parse(os.path.join(hole_path,hole_xml))

root_hole = tree_hole.getroot() # annotation

new_hole = tree_hole

tree_arm = parse(os.path.join(arm_path,hole_xml))

root_arm = tree_arm.getroot() # annotation

object = (tree_arm.findall('object'))

for i in range(len(object)):

root_hole.append(object[i])

__indent(root_hole)

new_hole.write(os.path.join(out_path,hole_xml))

# 不同名xml复制

else:

print('copying',hole_xml)

shutil.copy(os.path.join(hole_path,hole_xml), out_path)

# 将不同名xml复制

for arm_xml in os.listdir(arm_path):

if not os.path.exists(os.path.join(out_path,arm_xml)):

print('copying')

shutil.copy(os.path.join(arm_path, arm_xml), out_path)

参考链接:

原文链接:https://blog.csdn.net/weixin_41735859/article/details/107072533

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值