0.博主转换完格式后会有一行
<?xml version='1.0' encoding='utf-8'?>
处理方式如下:
1.YOLO格式的txt文件
图片中第一列为数据标签文件的类别的id
2.转换后的voc标签的xml文件
3. 首先将此代码复制到自己的python工程路径下
from xml.dom.minidom import Document
import os
import cv2
def makexml(txtPath, xmlPath, picPath): # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
"""此函数用于将yolo格式txt标注文件转换为voc格式xml标注文件
在自己的标注图片文件夹下建三个子文件夹,分别命名为picture、txt、xml
"""
# 本例中的标签有5个类,按照自己的类别进行更改
dic = {'0': "dog", # 创建字典用来对类型进行转换
'1': "person", # 此处的字典要与自己的classes.txt文件中的类对应,且顺序要一致
'2': "car",
'3': "bus",
'4': "bicycle"
}
files = os.listdir(txtPath)
for i, name in enumerate(files):
xmlBuilder = Document()
annotation = xmlBuilder.createElement("annotation") # 创建annotation标签
xmlBuilder.appendChild(annotation)
txtFile = open(txtPath + name)
txtList = txtFile.readlines()
img = cv2.imread(picPath + name[0:-4] + ".jpg")
Pheight, Pwidth, Pdepth = img.shape
folder = xmlBuilder.createElement("folder") # folder标签
foldercontent = xmlBuilder.createTextNode("my_person")
folder.appendChild(foldercontent)
annotation.appendChild(folder) # folder标签结束
filename = xmlBuilder.createElement("filename") # filename标签
filenamecontent = xmlBuilder.createTextNode(name[0:-4] + ".jpg")
filename.appendChild(filenamecontent)
annotation.appendChild(filename) # filename标签结束
path = xmlBuilder.createElement("path") # path标签
pathcontent = xmlBuilder.createTextNode("G:\darknet\My_Persons\my_person\\"+name[0:-4] + ".jpg")
path.appendChild(pathcontent)
annotation.appendChild(path) # path标签结束
source = xmlBuilder.createElement("source") # source标签
database = xmlBuilder.createElement("database") # source子标签database
databasecontent = xmlBuilder.createTextNode("Unknown")
database.appendChild(databasecontent)
source.appendChild(database) # source子标签database结束
annotation.appendChild(source) # source标签结束
size = xmlBuilder.createElement("size") # size标签
width = xmlBuilder.createElement("width") # size子标签width
widthcontent = xmlBuilder.createTextNode(str(Pwidth))
width.appendChild(widthcontent)
size.appendChild(width) # size子标签width结束
height = xmlBuilder.createElement("height") # size子标签height
heightcontent = xmlBuilder.createTextNode(str(Pheight))
height.appendChild(heightcontent)
size.appendChild(height) # size子标签height结束
depth = xmlBuilder.createElement("depth") # size子标签depth
depthcontent = xmlBuilder.createTextNode(str(Pdepth))
depth.appendChild(depthcontent)
size.appendChild(depth) # size子标签depth结束
annotation.appendChild(size) # size标签结束
for j in txtList:
oneline = j.strip().split(" ")
object = xmlBuilder.createElement("object") # object 标签
picname = xmlBuilder.createElement("name") # name标签
namecontent = xmlBuilder.createTextNode(dic[oneline[0]])
picname.appendChild(namecontent)
object.appendChild(picname) # name标签结束
pose = xmlBuilder.createElement("pose") # pose标签
posecontent = xmlBuilder.createTextNode("Unspecified")
pose.appendChild(posecontent)
object.appendChild(pose) # pose标签结束
truncated = xmlBuilder.createElement("truncated") # truncated标签
truncatedContent = xmlBuilder.createTextNode("0")
truncated.appendChild(truncatedContent)
object.appendChild(truncated) # truncated标签结束
difficult = xmlBuilder.createElement("difficult") # difficult标签
difficultcontent = xmlBuilder.createTextNode("0")
difficult.appendChild(difficultcontent)
object.appendChild(difficult) # difficult标签结束
bndbox = xmlBuilder.createElement("bndbox") # bndbox标签
xmin = xmlBuilder.createElement("xmin") # xmin标签
mathData = int(((float(oneline[1])) * Pwidth ) - (float(oneline[3])) * 0.5 * Pwidth)
xminContent = xmlBuilder.createTextNode(str(mathData))
xmin.appendChild(xminContent)
bndbox.appendChild(xmin) # xmin标签结束
ymin = xmlBuilder.createElement("ymin") # ymin标签
mathData = int(((float(oneline[2])) * Pheight) - (float(oneline[4])) * 0.5 * Pheight)
yminContent = xmlBuilder.createTextNode(str(mathData))
ymin.appendChild(yminContent)
bndbox.appendChild(ymin) # ymin标签结束
xmax = xmlBuilder.createElement("xmax") # xmax标签
mathData = int(((float(oneline[1])) * Pwidth ) + (float(oneline[3])) * 0.5 * Pwidth)
xmaxContent = xmlBuilder.createTextNode(str(mathData))
xmax.appendChild(xmaxContent)
bndbox.appendChild(xmax) # xmax标签结束
ymax = xmlBuilder.createElement("ymax") # ymax标签
mathData = int(((float(oneline[2])) * Pheight + 1) + (float(oneline[4])) * 0.5 * Pheight)
ymaxContent = xmlBuilder.createTextNode(str(mathData))
ymax.appendChild(ymaxContent)
bndbox.appendChild(ymax) # ymax标签结束
object.appendChild(bndbox) # bndbox标签结束
annotation.appendChild(object) # object标签结束
f = open(xmlPath + name[0:-4] + ".xml", 'w')
xmlBuilder.writexml(f, indent='', newl='\n', addindent='\t', encoding='utf-8')
f.close()
# 注意下面的路径要换成自己文件夹的路径,否则会报错
makexml("G:/darknet/My_Persons/txt/", "G:/darknet/My_Persons/xml3/",
"G:/darknet/My_Persons/picture/") # yolo标签的txt格式所在文件夹路径,voc标签的xml格式的文件保存路径,图片所在文件夹路径
4.找到如下代码
在上面的代码快的,大概118行,找到如下代码
按住ctrl键,鼠标点击红色方框中的方法
5.进入到该方法的源码中
该方法的源码是minidom.py,按照第四步就可进入如下的源码
def writexml(self, writer, indent="", addindent="", newl="", encoding=None):
if encoding is None:
writer.write('<?xml version="1.0" ?>'+newl)
else:
writer.write('<?xml version="1.0" encoding="%s"?>%s' % (
encoding, newl))
for node in self.childNodes:
node.writexml(writer, indent, addindent, newl)
6.找到第五步中的方法,大概在1789行中,注释掉里面的if else语句
def writexml(self, writer, indent="", addindent="", newl="", encoding=None):
# if encoding is None:
# writer.write('<?xml version="1.0" ?>'+newl)
# else:
# writer.write('<?xml version="1.0" encoding="%s"?>%s' % (
# encoding, newl))
for node in self.childNodes:
node.writexml(writer, indent, addindent, newl)
注释完后如上图所示
7.最后运行第三步中的代码
转换完成后,打开保存.xml文件的文件夹
结果如上图所示,转换完毕,谢谢。
借鉴:https://blog.csdn.net/weixin_43720657/article/details/107361479