1、yolo转xml
- from xml.dom.minidom import Document
- import os
- import cv2
- # def makexml(txtPath, xmlPath, picPath): # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
- def makexml(picPath, txtPath, xmlPath): # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
- """此函数用于将yolo格式txt标注文件转换为voc格式xml标注文件
- """
- dic = {'0': "plane", # 创建字典用来对类型进行转换
- '1': "baseball diamond", # 此处的字典要与自己的classes.txt文件中的类对应,且顺序要一致
- '2': "bridge",
- '3': "ground track field",
- '4': "small vehicle",
- '5': "large vehicle",
- '6': "ship",
- '7': "tennis court",
- '8': "basketball court",
- '9': "storage tank",
- '10': "soccer ball field",
- '11': "roundabout",
- '12': "harbor",
- '13': "swimming pool",
- '14': "helicopter",
- }
- 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("driving_annotation_dataset")
- 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标签结束
- 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 + 1) - (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 + 1) - (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 + 1) + (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='\t', newl='\n', addindent='\t', encoding='utf-8')
- f.close()
- if __name__ == "__main__":
- picPath = "./images/test/" # 图片所在文件夹路径,后面的/一定要带上
- txtPath = "./labels/test/" # txt所在文件夹路径,后面的/一定要带上
- xmlPath = "./annotations/test/" # xml文件保存路径,后面的/一定要带上
- makexml(picPath, txtPath, xmlPath)
复制代码 xml格式
- <?xml version="1.0" encoding="utf-8"?>
- <annotation>
- <folder>driving_annotation_dataset</folder>
- <filename>0.jpg</filename>
- <size>
- <width>640</width>
- <height>640</height>
- <depth>3</depth>
- </size>
- <object>
- <name>plane</name>
- <pose>Unspecified</pose>
- <truncated>0</truncated>
- <difficult>0</difficult>
- <bndbox>
- <xmin>315</xmin>
- <ymin>248</ymin>
- <xmax>422</xmax>
- <ymax>304</ymax>
- </bndbox>
- </object>
- </annotation>
复制代码 2、xml转dota
- import os
- import xml.etree.ElementTree as ET
- def convert_voc_to_dota_simple(xml_folder, output_folder):
- # 创建输出文件夹(如果不存在)
- if not os.path.exists(output_folder):
- os.makedirs(output_folder)
- # 遍历 XML 文件夹中的所有文件
- for xml_file in os.listdir(xml_folder):
- if xml_file.endswith('.xml'): # 只处理 XML 文件
- # 解析 XML 文件
- tree = ET.parse(os.path.join(xml_folder, xml_file))
- root = tree.getroot()
- # 初始化 DOTA 格式的字符串列表
- dota_annotations = []
- # 遍历 XML 中的 'object' 元素
- for obj in root.iter('object'):
- # 获取标准矩形边界框坐标
- bndbox = obj.find('bndbox')
- # 获取类别和难度级别
- category = obj.find('name').text
- difficult = obj.find('difficult').text
- # 提取矩形边界框的坐标
- xmin = int(bndbox.find('xmin').text)
- ymin = int(bndbox.find('ymin').text)
- xmax = int(bndbox.find('xmax').text)
- ymax = int(bndbox.find('ymax').text)
- # 将矩形边界框的四个角作为旋转边界框的顶点
- coords = [
- xmin, ymin, # 左上角
- xmax, ymin, # 右上角
- xmax, ymax, # 右下角
- xmin, ymax # 左下角
- ]
- # 将坐标、类别和难度级别转换为 DOTA 格式
- dota_format = ' '.join(map(str, coords + [category, difficult]))
- dota_annotations.append(dota_format)
- # 写入转换后的信息到 TXT 文件
- output_file_path = os.path.join(output_folder, xml_file.replace('.xml', '.txt'))
- with open(output_file_path, 'w') as f:
- for annotation in dota_annotations:
- f.write("%s\n" % annotation) # 每个注释占一行
- # 调用函数,传入 XML 文件夹路径和输出文件夹路径
- xml_folder = './annotations/val' # 请替换为您的 XML 文件夹路径
- output_folder = './DOTA_labels/val' # 请替换为您希望保存输出 TXT 文件的文件夹路径
- convert_voc_to_dota_simple(xml_folder, output_folder)
复制代码 3、验证dota 画框
- import xml.etree.ElementTree as ET
- import os
- import math
- import cv2
- import numpy as np
- import dota_utils as util
- import random
- img_root = r"./images/train/"
- label_root = r"./DOTA_labels/train/"
- drawed_img_root = r"./DOTA_labels_drawed/train/"
- image_name = os.listdir(img_root)
- for i in range(len(image_name)):
- img_path = os.path.join(img_root, image_name[i])
- label_path = os.path.join(label_root, image_name[i].split('.')[0] + '.txt')
- drawed_img_path = os.path.join(drawed_img_root, image_name[i])
- objects = util.parse_dota_poly(label_path)
- print(objects)
- img = cv2.imread(img_path)
- poly = []
- for i in range(len(objects)):
- poly.append(np.array(objects[i]['poly'], dtype=np.int32))
- print(poly)
- cv2.polylines(img, poly, isClosed=True, color=(35, 37, 133), thickness=2)
- drawed_img_path = drawed_img_path.replace('.bmp', '.png')
- cv2.imwrite(drawed_img_path, img)
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |