xml-dota-yolo数据集格式转换

打印 上一主题 下一主题

主题 853|帖子 853|积分 2561

1、yolo转xml
  1. from xml.dom.minidom import Document
  2. import os
  3. import cv2
  4. # def makexml(txtPath, xmlPath, picPath):  # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
  5. def makexml(picPath, txtPath, xmlPath):  # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
  6.     """此函数用于将yolo格式txt标注文件转换为voc格式xml标注文件
  7.     """
  8.     dic = {'0': "plane",  # 创建字典用来对类型进行转换
  9.            '1': "baseball diamond",  # 此处的字典要与自己的classes.txt文件中的类对应,且顺序要一致
  10.            '2': "bridge",
  11.            '3': "ground track field",
  12.            '4': "small vehicle",
  13.            '5': "large vehicle",
  14.            '6': "ship",
  15.            '7': "tennis court",
  16.            '8': "basketball court",
  17.            '9': "storage tank",
  18.            '10': "soccer ball field",
  19.            '11': "roundabout",
  20.            '12': "harbor",
  21.            '13': "swimming pool",
  22.            '14': "helicopter",
  23.            }
  24.     files = os.listdir(txtPath)
  25.     for i, name in enumerate(files):
  26.         xmlBuilder = Document()
  27.         annotation = xmlBuilder.createElement("annotation")  # 创建annotation标签
  28.         xmlBuilder.appendChild(annotation)
  29.         txtFile = open(txtPath + name)
  30.         txtList = txtFile.readlines()
  31.         img = cv2.imread(picPath + name[0:-4] + ".jpg")
  32.         Pheight, Pwidth, Pdepth = img.shape
  33.         folder = xmlBuilder.createElement("folder")  # folder标签
  34.         foldercontent = xmlBuilder.createTextNode("driving_annotation_dataset")
  35.         folder.appendChild(foldercontent)
  36.         annotation.appendChild(folder)  # folder标签结束
  37.         filename = xmlBuilder.createElement("filename")  # filename标签
  38.         filenamecontent = xmlBuilder.createTextNode(name[0:-4] + ".jpg")
  39.         filename.appendChild(filenamecontent)
  40.         annotation.appendChild(filename)  # filename标签结束
  41.         size = xmlBuilder.createElement("size")  # size标签
  42.         width = xmlBuilder.createElement("width")  # size子标签width
  43.         widthcontent = xmlBuilder.createTextNode(str(Pwidth))
  44.         width.appendChild(widthcontent)
  45.         size.appendChild(width)  # size子标签width结束
  46.         height = xmlBuilder.createElement("height")  # size子标签height
  47.         heightcontent = xmlBuilder.createTextNode(str(Pheight))
  48.         height.appendChild(heightcontent)
  49.         size.appendChild(height)  # size子标签height结束
  50.         depth = xmlBuilder.createElement("depth")  # size子标签depth
  51.         depthcontent = xmlBuilder.createTextNode(str(Pdepth))
  52.         depth.appendChild(depthcontent)
  53.         size.appendChild(depth)  # size子标签depth结束
  54.         annotation.appendChild(size)  # size标签结束
  55.         for j in txtList:
  56.             oneline = j.strip().split(" ")
  57.             object = xmlBuilder.createElement("object")  # object 标签
  58.             picname = xmlBuilder.createElement("name")  # name标签
  59.             namecontent = xmlBuilder.createTextNode(dic[oneline[0]])
  60.             picname.appendChild(namecontent)
  61.             object.appendChild(picname)  # name标签结束
  62.             pose = xmlBuilder.createElement("pose")  # pose标签
  63.             posecontent = xmlBuilder.createTextNode("Unspecified")
  64.             pose.appendChild(posecontent)
  65.             object.appendChild(pose)  # pose标签结束
  66.             truncated = xmlBuilder.createElement("truncated")  # truncated标签
  67.             truncatedContent = xmlBuilder.createTextNode("0")
  68.             truncated.appendChild(truncatedContent)
  69.             object.appendChild(truncated)  # truncated标签结束
  70.             difficult = xmlBuilder.createElement("difficult")  # difficult标签
  71.             difficultcontent = xmlBuilder.createTextNode("0")
  72.             difficult.appendChild(difficultcontent)
  73.             object.appendChild(difficult)  # difficult标签结束
  74.             bndbox = xmlBuilder.createElement("bndbox")  # bndbox标签
  75.             xmin = xmlBuilder.createElement("xmin")  # xmin标签
  76.             mathData = int(((float(oneline[1])) * Pwidth + 1) - (float(oneline[3])) * 0.5 * Pwidth)
  77.             xminContent = xmlBuilder.createTextNode(str(mathData))
  78.             xmin.appendChild(xminContent)
  79.             bndbox.appendChild(xmin)  # xmin标签结束
  80.             ymin = xmlBuilder.createElement("ymin")  # ymin标签
  81.             mathData = int(((float(oneline[2])) * Pheight + 1) - (float(oneline[4])) * 0.5 * Pheight)
  82.             yminContent = xmlBuilder.createTextNode(str(mathData))
  83.             ymin.appendChild(yminContent)
  84.             bndbox.appendChild(ymin)  # ymin标签结束
  85.             xmax = xmlBuilder.createElement("xmax")  # xmax标签
  86.             mathData = int(((float(oneline[1])) * Pwidth + 1) + (float(oneline[3])) * 0.5 * Pwidth)
  87.             xmaxContent = xmlBuilder.createTextNode(str(mathData))
  88.             xmax.appendChild(xmaxContent)
  89.             bndbox.appendChild(xmax)  # xmax标签结束
  90.             ymax = xmlBuilder.createElement("ymax")  # ymax标签
  91.             mathData = int(((float(oneline[2])) * Pheight + 1) + (float(oneline[4])) * 0.5 * Pheight)
  92.             ymaxContent = xmlBuilder.createTextNode(str(mathData))
  93.             ymax.appendChild(ymaxContent)
  94.             bndbox.appendChild(ymax)  # ymax标签结束
  95.             object.appendChild(bndbox)  # bndbox标签结束
  96.             annotation.appendChild(object)  # object标签结束
  97.         f = open(xmlPath + name[0:-4] + ".xml", 'w')
  98.         xmlBuilder.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
  99.         f.close()
  100. if __name__ == "__main__":
  101.     picPath = "./images/test/"  # 图片所在文件夹路径,后面的/一定要带上
  102.     txtPath = "./labels/test/"  # txt所在文件夹路径,后面的/一定要带上
  103.     xmlPath = "./annotations/test/"  # xml文件保存路径,后面的/一定要带上
  104.     makexml(picPath, txtPath, xmlPath)
复制代码
xml格式
  1. <?xml version="1.0" encoding="utf-8"?>
  2.         <annotation>
  3.                 <folder>driving_annotation_dataset</folder>
  4.                 <filename>0.jpg</filename>
  5.                 <size>
  6.                         <width>640</width>
  7.                         <height>640</height>
  8.                         <depth>3</depth>
  9.                 </size>
  10.                 <object>
  11.                         <name>plane</name>
  12.                         <pose>Unspecified</pose>
  13.                         <truncated>0</truncated>
  14.                         <difficult>0</difficult>
  15.                         <bndbox>
  16.                                 <xmin>315</xmin>
  17.                                 <ymin>248</ymin>
  18.                                 <xmax>422</xmax>
  19.                                 <ymax>304</ymax>
  20.                         </bndbox>
  21.                 </object>
  22.         </annotation>
复制代码
2、xml转dota
  1. import os
  2. import xml.etree.ElementTree as ET
  3. def convert_voc_to_dota_simple(xml_folder, output_folder):
  4.     # 创建输出文件夹(如果不存在)
  5.     if not os.path.exists(output_folder):
  6.         os.makedirs(output_folder)
  7.     # 遍历 XML 文件夹中的所有文件
  8.     for xml_file in os.listdir(xml_folder):
  9.         if xml_file.endswith('.xml'):  # 只处理 XML 文件
  10.             # 解析 XML 文件
  11.             tree = ET.parse(os.path.join(xml_folder, xml_file))
  12.             root = tree.getroot()
  13.             # 初始化 DOTA 格式的字符串列表
  14.             dota_annotations = []
  15.             # 遍历 XML 中的 'object' 元素
  16.             for obj in root.iter('object'):
  17.                 # 获取标准矩形边界框坐标
  18.                 bndbox = obj.find('bndbox')
  19.                 # 获取类别和难度级别
  20.                 category = obj.find('name').text
  21.                 difficult = obj.find('difficult').text
  22.                 # 提取矩形边界框的坐标
  23.                 xmin = int(bndbox.find('xmin').text)
  24.                 ymin = int(bndbox.find('ymin').text)
  25.                 xmax = int(bndbox.find('xmax').text)
  26.                 ymax = int(bndbox.find('ymax').text)
  27.                 # 将矩形边界框的四个角作为旋转边界框的顶点
  28.                 coords = [
  29.                     xmin, ymin,  # 左上角
  30.                     xmax, ymin,  # 右上角
  31.                     xmax, ymax,  # 右下角
  32.                     xmin, ymax  # 左下角
  33.                 ]
  34.                 # 将坐标、类别和难度级别转换为 DOTA 格式
  35.                 dota_format = ' '.join(map(str, coords + [category, difficult]))
  36.                 dota_annotations.append(dota_format)
  37.             # 写入转换后的信息到 TXT 文件
  38.             output_file_path = os.path.join(output_folder, xml_file.replace('.xml', '.txt'))
  39.             with open(output_file_path, 'w') as f:
  40.                 for annotation in dota_annotations:
  41.                     f.write("%s\n" % annotation)  # 每个注释占一行
  42. # 调用函数,传入 XML 文件夹路径和输出文件夹路径
  43. xml_folder = './annotations/val'  # 请替换为您的 XML 文件夹路径
  44. output_folder = './DOTA_labels/val'  # 请替换为您希望保存输出 TXT 文件的文件夹路径
  45. convert_voc_to_dota_simple(xml_folder, output_folder)
复制代码
3、验证dota 画框
  1. import xml.etree.ElementTree as ET
  2. import os
  3. import math
  4. import cv2
  5. import numpy as np
  6. import dota_utils as util
  7. import random
  8. img_root = r"./images/train/"
  9. label_root = r"./DOTA_labels/train/"
  10. drawed_img_root = r"./DOTA_labels_drawed/train/"
  11. image_name = os.listdir(img_root)
  12. for i in range(len(image_name)):
  13.     img_path = os.path.join(img_root, image_name[i])
  14.     label_path = os.path.join(label_root, image_name[i].split('.')[0] + '.txt')
  15.     drawed_img_path = os.path.join(drawed_img_root, image_name[i])
  16.     objects = util.parse_dota_poly(label_path)
  17.     print(objects)
  18.     img = cv2.imread(img_path)
  19.     poly = []
  20.     for i in range(len(objects)):
  21.         poly.append(np.array(objects[i]['poly'], dtype=np.int32))
  22.     print(poly)
  23.     cv2.polylines(img, poly, isClosed=True, color=(35, 37, 133), thickness=2)
  24.     drawed_img_path = drawed_img_path.replace('.bmp', '.png')
  25.     cv2.imwrite(drawed_img_path, img)
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

tsx81428

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表