目标检测中将xml标签转换为txt(voc格式转换为yolo)
xml格式:
".xml"格式是可扩展标记语言,因其可以跨越多平台的属性,成为网络数据传输的重要工具。如下图所示,xml格式数据特点就是简单易理解,清晰易操控。我们可以清晰的看到这个数据的文件夹,文件名,路径,来源,格式,目标对象的类别,位置等信息。
txt格式:
“.txt”格式就是最常见的文本类型,这种格式保存的内容简单,占用的内存小。如下图所示,为用notebook打开的一个目标检测数据的类别标签,它有两个目标物体,一行代表一个,类别标签后的四个浮点数代表目标的中心位置x,y和长宽w,h(以一副图片左上角为原点的相对位置)。因txt为保存的目标检测数据没有类别名称,所以通常会在一系列类别文件后,有一个classes.txt,用来保存类名称。
xml格式转换为txt:
通常的voc数据集会有三个文件,一个是JPEGImages,用来保存原始图像;第二个是Annotations,用来保存标签信息,它一般与JPEGImages中的图像一一对应,即JPEGImages中每幅图像在Annotations中有与它一一对应的xml文件;第三个是ImageSets,它包含一个Main的子文件夹,Main中含有至少三个txt文件,分别为train.txt,test.txt,val.txt,记录训练、测试、验证集的图像序号。在接下来的代码中我们分别生成三个文件夹,用来保存训练、测试、验证的txt标签。
xml格式记录的信息多,转向txt也较为简单,只用把相应的信息进行提取即可。
首先导包,都是很简单的包,一般下载编译器自带的。
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
然后获取全部的类别标签,因为xml的类别信息保存在每个xml文件中,没有一起的类别展示。而用于yolo的txt需要一个完整的类别文件描述。
# 获取全部类别标签
#image_id是每个xml的名称
classes = []
def gen_classes(image_id):
in_file = open('%s/Annotations/%s.xml'%(path,image_id))
tree = ET.parse(in_file)
root = tree.getroot()
for obj in root.iter('object'):
cls_name = obj.find('name').text
if cls_name in classes:
pass
else:
classes.append(cls_name)
return classes
将实际位置坐标转换为相对位置坐标的代码,其中size是图片大小,box是目标物品的位置。
#改变坐标格式
def convert(size, box):
dw = 1./(size[0])
dh = 1./(size[1])
x = (box[0] + box[1])/2.0
y = (box[2] + box[3])/2.0
w = box[1] - box[0]
h = box[3] - box[2]
x = x*dw
w = w