【xml】【精灵标注助手】【标签读取与重写】

顶部位置

具体内容

1. 精灵标注助手的标注结果

返回顶部

<?xml version="1.0" ?>
<doc>
	<path>6695.png</path>
	<outputs>
		<object>
			<item>
				<name>face</name>
				<bndbox>
					<xmin>51</xmin>
					<ymin>36</ymin>
					<xmax>103</xmax>
					<ymax>91</ymax>
				</bndbox>
			</item>
			<item>
				<name>smoke</name>
				<bndbox>
					<xmin>3</xmin>
					<ymin>172</ymin>
					<xmax>27</xmax>
					<ymax>206</ymax>
				</bndbox>
			</item>
		</object>
	</outputs>
	<time_labeled>1613973666698</time_labeled>
	<labeled>true</labeled>
	<size>
		<width>165</width>
		<height>339</height>
		<depth>3</depth>
	</size>
</doc>

2. code: 将精灵标注结果改为voc格式标注结果

返回顶部

# -*- coding:utf-8 -*-
''' 重写 xml 文件时需要的信息

filename 对应的图片名称

width   有
height  有
depth   有

标记框信息:
name    标签名
xyxy    标记框信息
'''
import os
from xml.dom import minidom
import xml.etree.ElementTree as ET

### 提取精灵标注助手中的标注结果
# 传入存储 xml 文件的根路径 --> 以字典的形式返回 xml 文件中存储的数据信息,一个 xml 文件构成一条字典记录
def extract_xml_info(xml_path):
    tree = ET.parse(xml_path)
    ### 对应图片名称
    filename = os.path.basename(xml_path)
    # print(filename)
    ### 图像宽、高、深度
    width = float(tree.find('size').find('width').text)     # 图片的高
    height = float(tree.find('size').find('height').text)   # 图片的宽
    depth = float(tree.find('size').find('depth').text)     # 图片的深度
    # print(width, height, depth)
    ### 标记框的 标签名 和 标记框信息
    objs = tree.find('outputs').find('object').findall('item')  # 获取xml文件中所有的标记框
    bbox_list = []
    for obj in objs:
        label_name = obj.find('name').text
        xmin = int(obj.find('bndbox').find('xmin').text)
        ymin = int(obj.find('bndbox').find('ymin').text)
        xmax = int(obj.find('bndbox').find('xmax').text)
        ymax = int(obj.find('bndbox').find('ymax').text)
        bbox = [label_name, xmin, ymin, xmax, ymax]
        bbox_list.append(bbox)
        # print(label_name, bbox)
    ### 将主要信息,以字典形式进行保存
    xml_dict = {
    
     'filename':filename, 'width':int(width) , 'height':int(height) , 'depth':int(depth) , 'bbox_list':bbox_list }
    return xml_dict

### 将已经提取的信息写成 labelimg 可以读取的格式
def write_xml(xml_dict, xml_save_path):
    ### 解析字典中的元素
    filename = xml_dict['filename']
    width = xml_dict['width']
    height = xml_dict['height']
    depth = xml_dict['depth']
    bbox_list = xml_dict['bbox_list']
    # print(filename, width, height, depth, bbox_list)
    ### 将以上信息,重写成 labelimg 可以读取的方式
    # 1.创建 DOM 树对象
    dom = minidom.Document()
    # 2.创建根节点。每次都要用DOM对象来创建任何节点。
    root_node = dom.createElement('annotation')
    # 3.用 DOM 对象添加根节点
    dom.appendChild(root_node)
    ### folder 子节点
    folder_node = dom.createElement('folder')  # 创建子节点
    root_node.appendChild(folder_node)         # 将创建的子节点挂到根节点上
    folder_text = dom.createTextNode('smoke-1')    # 创建文本节点
    folder_node.appendChild(folder_text)       # 将创建的文本节点挂到子节点上
    ### filename 子节点, 需要传进参数 filename
    filename_node = dom.createElement('filename')
    root_node.appendChild(filename_node)
    filename_text = dom.createTextNode(filename)
    filename_node.appendChild(filename_text)
    ### size 子节点,需要传进参数 w、h、c
    size_node = dom.createElement('size')
    root_node.appendChild(size_node)
    # width
    width_node = dom.createElement('width')
    size_node.appendChild(width_node)
    width_text = dom.createTextNode(str(width))
    width_node.appendChild(width_text)
    # height
    height_node = dom.createElement('height')
    size_node.appendChild(height_node)
    height_text = dom.createTextNode(str(height))
    height_node.appendChild(height_text)
    # depth
    depth_node = dom.createElement('depth')
    size_node.appendChild(depth_node)
    depth_text = dom.createTextNode(str(depth))
    depth_node.appendChild(depth_text)
    ### 创建 object 节点
    for bbox in bbox_list:
        object_node = dom.createElement('object')
        root_node.appendChild(object_node)
        ### 标签名称
        name_node = dom.createElement('name')
        object_node.appendChild(name_node)
        name_text = dom.createTextNode(str(bbox[0]))
        name_node.appendChild(name_text)
        ### 标记框信息
        bndbox_node = dom.createElement('bndbox')
        object_node.appendChild(bndbox_node)
        # xmin
        xmin_node = dom.createElement('xmin')
        bndbox_node.appendChild(xmin_node)
        xmin_text = dom.createTextNode(str(bbox[1]))
        xmin_node.appendChild(xmin_text)
        # ymin
        ymin_node = dom.createElement('ymin')
        bndbox_node.appendChild(ymin_node)
        ymin_text = dom.createTextNode(str(bbox[2]))
        ymin_node.appendChild(ymin_text)
        # xmax
        xmax_node = dom.createElement('xmax')
        bndbox_node.appendChild(xmax_node)
        xmax_text = dom.createTextNode(str(bbox[3]))
        xmax_node.appendChild(xmax_text)
        # ymax
        ymax_node = dom.createElement('ymax')
        bndbox_node.appendChild(ymax_node)
        ymax_text = dom.createTextNode(str(bbox[4]))
        ymax_node.appendChild(ymax_text)
    ### 每一个结点对象(包括dom对象本身)都有输出XML内容的方法,如:toxml()--字符串, toprettyxml()--美化树形格式。
    try:
        with open(xml_save_path,'w',encoding='UTF-8') as fh:
            # 4.writexml()第一个参数是目标文件对象,第二个参数是根节点的缩进格式,第三个参数是其他子节点的缩进格式,
            # 第四个参数制定了换行格式,第五个参数制定了xml内容的编码。
            dom.writexml(fh,indent='',addindent='\t',newl='\n',encoding='UTF-8')
            # print('{}\t对应的 xml 文件创建成功。'.format(filename))
    except Exception as err:
        print('错误:{err}'.format(err=err))

### 遍历文件,找到 xml 文件之后就提取信息 + 重写 xml 文件
def ergodic_xml(xml_folder_path, xml_folder_path_save):
    xml_filenames = os.listdir(xml_folder_path)
    xml_index = 0
    for xml_filename in xml_filenames:
        # 不是xml文件就跳过
        if xml_filename.split('.')[-1] != 'xml':
            continue
        xml_index = xml_index + 1
        xml_path = os.path.join(xml_folder_path, xml_filename)
        ### 读取 xml 文件中的标记信息
        xml_info = extract_xml_info(xml_path)
        print('{:<3d}\t{}\t{}'.format(xml_index, xml_filename, xml_info))
        ### 重写可以被labelimg读取的 xml 文件
        xml_save_path = os.path.join(xml_folder_path_save, xml_filename)
        write_xml(xml_info, xml_save_path)

########################### 主函数 ##############################
### 第 4 批
xml_folder_path = r'./data/xml'
xml_folder_path_save = r'./data/xml_voc'
ergodic_xml(xml_folder_path, xml_folder_path_save)

3. 改写后的xml文件内容

返回顶部

<?xml version="1.0" encoding="UTF-8"?>
<annotation>
	<folder>smoke-1</folder>
	<filename>6695.xml</filename>
	<size>
		<width>165</width>
		<height>339</height>
		<depth>3</depth>
	</size>
	<object>
		<name>face</name>
		<bndbox>
			<xmin>51</xmin>
			<ymin>36</ymin>
			<xmax>103</xmax>
			<ymax>91</ymax>
		</bndbox>
	</object>
	<object>
		<name>smoke</name>
		<bndbox>
			<xmin>3</xmin>
			<ymin>172</ymin>
			<xmax>27</xmax>
			<ymax>206</ymax>
		</bndbox>
	</object>
</annotation>

4. 内容4

返回顶部

在这里插入代码片

5. 内容5

返回顶部

在这里插入代码片

6. 内容6

返回顶部

在这里插入代码片

猜你喜欢

转载自blog.csdn.net/qq_32342205/article/details/128671128