• 将labelImg生成的指定xml标签中某一类的检测框复制给其他图片的xml


    应用背景:

    我们在针对监控视频进行多目标labelImg标注时,有些目标检测框的位置时不变的(例如监控镜头下的固定设备),有些目标的检测框是实时变化的(例如监控镜头下的人)。

    我们的目标就是将固定不变的类的检测框信息分享给其他所有的标签,我们只需要标注那些变化的标签。

    整体功能:

    复制指定xml标签中的指定类,复制给目标图像目录内所有图像对应的标签。
    情况一:图像没有对应的xml标签,创建一个新的xml标签,并且复制模板xml中指定类所有检测框信息
    情况一:图像已经生成了的xml标签,那么就在原有的xml文件中,添加上模板xml中指定类所有检测框信息,而这个xml标签中的其他检测框信息依旧保留。

    代码:

    import os
    import numpy as np
    import xml.etree.ElementTree as ET
    
    # 提供原图目录的路径
    root_path = r"D:\dataset\dataset_labeling\coal-D"
    # 提供一个标签文件模板
    # 脚本会根据这个模板的xml文件的标注信息,为图像中所有的图像提供xml文件
    template_xml =  r"D:\dataset\dataset_labeling\coal-D\2B-coal (553).xml"
    # 载入模板xml文件
    tree = ET.parse(template_xml)
    classes = ['coal']
    
    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 not in target_classes_lower):
                tree_root.remove(parent_node)
    
    
    def add_node_by_target_classes(nodelist, target_classes_lower, tree_root):
        print(222)
        for parent_node in nodelist:
            # print(333)
            children = parent_node.getchildren()
            # print(children[0].text)
            if (parent_node.tag == "object" and children[0].text  in target_classes_lower):
                # print(children[0].text.lower())
                tree_root.append(parent_node)
    
    def find_nodes(tree, path):
        return tree.findall(path)
    
    
    for root, dir, files in os.walk(root_path):
        for file in files:
        	# 判断是否为jpg文件,如果只是图像目录中一部分图像共享同一种标注文件,则需要针对文件名进行二次判断。
            # if file.split('.')[-1] == 'jpg':
            if file.split('.')[-1] == 'jpg' and int(file.split('(')[-1].split(')')[0]) > 344:
                print(int(file.split('(')[-1].split(')')[0]))
                xml_name = file.split('.')[0] + '.xml'
                if os.path.exists(os.path.join(root_path, xml_name)):
                    print('1111')
                    new_tree = ET.parse(os.path.join(root_path, xml_name))
                    old_root = tree.getroot()
                    new_root = new_tree.getroot()
                    # get parent nodes
                    add_parent_nodes = find_nodes(old_root, "./")
                    # get target classes and add
                    target_del_node = add_node_by_target_classes(add_parent_nodes, classes, new_root)
                    new_tree.write(os.path.join(root_path, xml_name), encoding="utf-8", xml_declaration=True)	# 输出新的xml文件
                    # print(os.path.join(root_path, xml_name))
                else:
                    xml_path = os.path.join(root_path, xml_name) # 生成新的xml的地址
                    new_tree = tree	# 复制xml信息
                    new_root = new_tree.getroot()
                    sub1 = new_root.find('filename')  # 找到filename标签,
                    sub1.text = file  # 修改filename标签内容
                    sub2 = new_root.find('path')  # 找到path标签,
                    sub2.text = os.path.join(root_path, file)  # 修改path标签内容
                    # get parent nodes
                    del_parent_nodes = find_nodes(new_root, "./")
                    # get target classes and delete
                    target_del_node = del_node_by_target_classes(del_parent_nodes, classes, new_root)
    
                    new_tree.write(xml_path, encoding="utf-8", xml_declaration=True)	# 输出新的xml文件
                    # print(xml_path)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
  • 相关阅读:
    微信小程序——简易复制文本
    公众号的附件怎么上传(如Word、Excel、Pdf等)
    阿里三面:Redis大key怎么处理?
    接口封装如何实现?
    CH59X/CH58X/CH57X PWM使用
    手撸二叉树——二叉查找树
    轻量应用服务器vs云服务器:区别在哪?
    libyuv 再次封装打包与测试
    计算机毕业设计之java+springcloud基于vue的智慧养老平台-老人信息管理-敬老院管理系统
    Discrete Optimization课程笔记(1)—Knapsack Problem
  • 原文地址:https://blog.csdn.net/sazass/article/details/127809754