python xml常见操作

目标检测任务中,输入为一张图片以及目标框的坐标,在标注工具标注完成后,通常坐标会保存在xml文件中。当我们根据自己的业务需求,需要修改标注数据时,由于重新标注的成本较高,所以直接修改xml文件较为合适。

当前我使用的标注工具是LableImg的Ubuntu版本:

github:https://github.com/chinakook/labelImg2

             https://github.com/tzutalin/labelImg

首先是创建xml文件,代码如下:

import xml.etree.ElementTree as ET
import numpy as np
import os

path = '../data/Images'
label_path = '../data/label'
input_path = '../data/Input'
annotation_path = '../data/Annotation'

for img_path in images:
    img = cv2.imread(os.path.join(path, img_path))

    x = []
    y = []    
    root = ET.Element("annotation")
    filename = ET.SubElement(root, "filename")
    filepath = ET.SubElement(root, "filepath")
    size = ET.SubElement(root, "size")
    width = ET.SubElement(size, "width")
    height = ET.SubElement(size, "height")
    depth = ET.SubElement(size, "depth")
    object_ = ET.SubElement(root, "object")
    name = ET.SubElement(object_, "name")
    bndbox = ET.SubElement(object_, "bndbox")
    xmin = ET.SubElement(bndbox, "xmin")
    ymin = ET.SubElement(bndbox, "ymin")
    xmax = ET.SubElement(bndbox, "xmax")
    ymax = ET.SubElement(bndbox, "ymax")
    filename.text = img_path
    filepath.text = os.path.join(path, img_path)
    width.text = str(img.shape[0])
    height.text = str(img.shape[1])
    depth.text = str(img.shape[2])
    name.text = "name"


    # 请根据个人需求修改[xmin, ymin, xmax, ymax]的值的获取方式
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            if img[i][j][0] == 0 and img[i][j][2] == 255:
                x.append(j)
                y.append(i)
    xmin.text = str(np.min(x))
    ymin.text = str(np.min(y))
    xmax.text = str(np.max(x))
    ymax.text = str(np.max(y))

    tree = ET.ElementTree(root)
    tree.write(os.path.join(annotation_path, img_path.split('.')[0]+".xml"))

修改xml文件:

for xml_file in xml_list:

    updateTree = ET.parse(os.path.join(xml_dir, xml_file))
    root = updateTree.getroot()
    sub1 = root.findall("object")
    for object_ in sub1:
        sub2 = object_.find("name")
        if sub2.text == 'A':
            sub2.text = 'B'
    updateTree.write(os.path.join(xml_dir, xml_file))

删除某个类的目标框:

for xml_path in xml_list:
    tree = ET.parse(os.path.join(xml_dir_path, xml_path))

    root = tree.getroot()

    for obj in root.findall('object'):
        if obj.find('name').text == 'B':
            root.remove(obj)
    tree.write(os.path.join(xml_dir_path, xml_path))

修改或删除完成后,都要记得使用write覆盖原xml文件

猜你喜欢

转载自blog.csdn.net/huang_nansen/article/details/90141780