IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> yolo(darkent)格式转换为pascal VOC数据格式 -> 正文阅读

[人工智能]yolo(darkent)格式转换为pascal VOC数据格式

yolo(darkent)格式转换为pascal VOC数据格式

一、认识VOC和YOLO数据格式

在这里插入图片描述
pascal VOC数据的标注格式为边框的(左上x,左上y,右下x,右下y)的坐标值,并且没有归一化,而yolo数据标注格式为(分类的id, 中心点坐标x,中心点坐标y,框的宽,框的高),yolo的数据标注格式是进行了归一化的。

pascal VOC数据标注的存储文件为XML,接下来简单地介绍一下XML文件。
XML文件的一个节点的基本结构为
在这里插入图片描述
VOC数据标注文件
以下就是一个标准的VOC标注文件。

<annotation>
	<folder>VOC2007</folder>
	<filename>000002.jpg</filename>
	<source>
		<database>The VOC2007 Database</database>
		<annotation>PASCAL VOC2007</annotation>
		<image>flickr</image>
		<flickrid>329145082</flickrid>
	</source>
	<owner>
		<flickrid>hiromori2</flickrid>
		<name>Hiroyuki Mori</name>
	</owner>
	<size>
		<width>335</width>
		<height>500</height>
		<depth>3</depth>
	</size>
	<segmented>0</segmented>
	<object>
		<name>train</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>139</xmin>
			<ymin>200</ymin>
			<xmax>207</xmax>
			<ymax>301</ymax>
		</bndbox>
	</object>
</annotation>

二、构建xml的基本操作

使用python的xml.etree.ElementTree模块可以很方便地构建和解析xml文件,以下代码全部使用该库进行构建。

基本操作如下
在这里插入图片描述
举个例子,我们来构建一个最基本的xml文件

#   指定根节点tag是 'data'
root = ET.Element('data') 
#   指定data的子节点是country,并且attrib是'name' = Liechtenstein'
country = ET.SubElement(root,'country', {'name':'Liechtenstein'})
#   指定country的子节点是rank, rank.text = 1
rank = ET.SubElement(country,'rank')
rank.text = '1'
year = ET.SubElement(country,'year')
year.text = '2008'
#   构建tree
tree=ET.ElementTree(root)
#   写入tree
tree.write("demo.xml")

我们写入了一个基本的文件,文件名为demo.xml,打开该文件我们可以查看我们写入的xml结构

<data><country name="Liechtenstein"><rank>1</rank><year>2008</year></country></data>

可以看出,这样生成的xml文件并不美观,和VOC数据标注格式相比,可读性非常差。因此我们需要美化xml文件。

三、美化xml文件

使用以下脚本进行xml文件美化

def prettyXml(tree,indent='\t',newline='\n',level=0):
    """
    Pretty Xml File before writing
    :param tree: 创建好的父节点,未初始化的tree
    :param indent: 缩进“\t”
    :param newline: 换行“\n”
    :param level: 用于递归操作的变量,实现不同级别节点增加不同数量的缩进“\t”
    :return: 无
    """
    treeList=list(tree)
    for subElement in treeList:
        if treeList.index(subElement) < (len(treeList) - 1):
            subElement.tail=newline+indent*(level+1)
        else:
            subElement.tail=newline+indent*level
        prettyXml(subElement,indent,newline,level+1)
#   指定根节点tag是 'data'
root = ET.Element('data') 
#   指定data的子节点是country,并且attrib是'name' = Liechtenstein'
country = ET.SubElement(root,'country', {'name':'Liechtenstein'})
#   指定country的子节点是rank, rank.text = 1
rank = ET.SubElement(country,'rank')
rank.text = '1'
year = ET.SubElement(country,'year')
year.text = '2008'
#   构建tree
prettyXml(root)
tree=ET.ElementTree(root)
#   写入tree
tree.write("demo2.xml")

美化后的demo2.xml文件如下

<data><country name="Liechtenstein"><rank>1</rank>
		<year>2008</year>
	</country>
</data>

四、Yolo数据标注格式 to VOC数据标注格式

'''
Description: 
coding: utf-8
language: python3.8, tensorflow2.6
Author: JiaHao Shum
Date: 2022-03-20 16:09:52
'''

import numpy as np
from PIL import Image, ImageDraw
import os
import xml.etree.ElementTree as ET
from tqdm import tqdm

#	图片中包含的分类,需要和yolo中的class_id对应起来
classes = ['face', 'face with mask']

#	yolo格式标注文件存放路径
yolo_labels_dir = './Labels'
#	图片存放路径
images_dir = './JPEGImages'
#	voc格式标注文件存放路径
pascal_labels_dir = './XMLs'


def prettyXml(tree,indent='\t',newline='\n',level=0):
    """
    Pretty Xml File before writing
    :param tree: 创建好的父节点,未初始化的tree
    :param indent: 缩进“\t”
    :param newline: 换行“\n”
    :param level: 用于递归操作的变量,实现不同级别节点增加不同数量的缩进“\t”
    :return: 无
    """
    treeList=list(tree)
    for subElement in treeList:
        if treeList.index(subElement) < (len(treeList) - 1):
            subElement.tail=newline+indent*(level+1)
        else:
            subElement.tail=newline+indent*level
        prettyXml(subElement,indent,newline,level+1)


def convert_one_label(yolo_filename, images_dir, xml_save_path):
    """
    Func:
        将一张图片的yolo格式的标签转换成xml格式
    Args:
        yolo_filename:  yolo格式标签的完整路径
        images_dir:     images的存放地址
        xml_save_path:  xml格式标签的存放地址
    """
    
    filename = os.path.split(yolo_filename)[-1]
    image_filename = os.path.join(images_dir, str(filename[:-4]) + '.jpg')

    image = Image.open(image_filename)
    iw, ih = image.size

    """获得一张图片的yolo box"""
    if not os.path.exists(xml_save_path):
        os.makedirs(xml_save_path)
        
    bndbox = open(yolo_filename).readlines()
    bndbox = [x.strip() for x in bndbox]
    boxes_org = np.array([x.split() for x in bndbox], dtype='float32')
    boxes = np.zeros_like(boxes_org, dtype='int')
    boxes[:, -1] = boxes_org[:, 0].astype('int')
    boxes[:, 0] = (boxes_org[:, 1] - boxes_org[:, 3] / 2) * iw
    boxes[:, 1] = (boxes_org[:, 2] - boxes_org[:, 4] / 2) * ih
    boxes[:, 2] = (boxes_org[:, 1] + boxes_org[:, 3] / 2) * iw
    boxes[:, 3] = (boxes_org[:, 2] + boxes_org[:, 4] / 2) * ih

    """写入一张图片的xml"""
    xml_filename = os.path.join(xml_save_path, str(filename[:-4])+'.xml')

    root = ET.Element('annotation')
    root.text = '\n\t'

    for box in boxes:
        obj = ET.SubElement(root, 'object')
        
        name = ET.SubElement(obj, 'name')
        name.text = classes[box[-1]]
        
        bndbox = ET.SubElement(obj, 'bndbox')
       
        xmin = ET.SubElement(bndbox, 'xmin')
        ymin = ET.SubElement(bndbox, 'ymin')
        xmax = ET.SubElement(bndbox, 'xmax')
        ymax = ET.SubElement(bndbox, 'ymax')
        xmin.text,  = str(box[0]), 
        ymin.text,  = str(box[1]), 
        xmax.text,  = str(box[2]), 
        ymax.text,  = str(box[3]), 
    
    prettyXml(root)
    tree = ET.ElementTree(root)
    tree.write(xml_filename)


if __name__ == '__main__':

    filenames = os.listdir(yolo_labels_dir)
    filenames = [str(x) for x in filenames if x.endswith('.txt')]

    for filename in tqdm(filenames):
        yolo_filename = os.path.join(yolo_labels_dir, filename)
        convert_one_label(yolo_filename, images_dir, pascal_labels_dir)
    
    print('-'*50)
    print('Convertion Finish!')
    print('-'*50)

运行结果如下:
在这里插入图片描述
我们进入相应文件查看一下:
在这里插入图片描述

在这里插入图片描述
可见我们已经成功转换

五、Reference

http://www.4k8k.xyz/article/weixin_42997255/100090114
https://docs.python.org/zh-cn/3.9/library/xml.etree.elementtree.html?highlight=subelement#xml.etree.ElementTree.SubElement
https://blog.csdn.net/weixin_42782150/article/details/106219001
https://blog.csdn.net/jq_98/article/details/123316087
https://blog.csdn.net/qq_39507748/article/details/110819929

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:50:48  更:2022-03-21 20:51:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:30:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码