当前位置:   article > 正文

Python DOTA与PASCAL VOC格式标签数据的相互转化_voc转dota

voc转dota

DOTA数据集是遥感影像目标检测的常用标准数据集,其标签文件以txt的形式存储,一个txt对应一张样本影像,txt中的每一行对应影像中的一个目标,每个目标的外围边界框表示为【 x1 y1 x2 y2 x3 y3 x4 y4 label difficult 】,具体如下所示:

 PASCAL VOC也是目标检测、图像分割任务中常用的基准数据之一,其样本标签以xml的文件形式存储,每个xml对应一张样本影像,object的边界框信息由顶点坐标值【xmin ymin xmax ymax】表示,具体如下所示:

有时候,我们同时想用倾斜框和矩形框模型对目标进行检测,就可以将标记的DOTA格式的倾斜框坐标转化为PASCAL VOC格式的矩形框坐标,转化方式如下所示:

  1. import os
  2. from xml.dom.minidom import Document
  3. from xml.dom.minidom import parse
  4. import xml.dom.minidom
  5. import numpy as np
  6. import csv
  7. import cv2
  8. import string
  9. def poly2rect(box_list):
  10. box_list = np.array(box_list)
  11. x, y, w, h = cv2.boundingRect(box_list)
  12. xmin = x - w / 2.0
  13. ymin = y - h / 2.0
  14. xmax = x + w / 2.0
  15. ymax = y + h / 2.0
  16. return xmin, ymin, xmax, ymax
  17. def WriterXMLFiles(filename, path, box_list, label_list, w, h, d):
  18. # dict_box[filename]=json_dict[filename]
  19. doc = xml.dom.minidom.Document()
  20. root = doc.createElement('annotation')
  21. doc.appendChild(root)
  22. foldername = doc.createElement("folder")
  23. foldername.appendChild(doc.createTextNode("JPEGImages"))
  24. root.appendChild(foldername)
  25. nodeFilename = doc.createElement('filename')
  26. nodeFilename.appendChild(doc.createTextNode(filename))
  27. root.appendChild(nodeFilename)
  28. pathname = doc.createElement("path")
  29. pathname.appendChild(doc.createTextNode("xxxx"))
  30. root.appendChild(pathname)
  31. sourcename = doc.createElement("source")
  32. databasename = doc.createElement("database")
  33. databasename.appendChild(doc.createTextNode("The VOC2007 Database"))
  34. sourcename.appendChild(databasename)
  35. annotationname = doc.createElement("annotation")
  36. annotationname.appendChild(doc.createTextNode("PASCAL VOC2007"))
  37. sourcename.appendChild(annotationname)
  38. imagename = doc.createElement("image")
  39. imagename.appendChild(doc.createTextNode("flickr"))
  40. sourcename.appendChild(imagename)
  41. flickridname = doc.createElement("flickrid")
  42. flickridname.appendChild(doc.createTextNode("0"))
  43. sourcename.appendChild(flickridname)
  44. root.appendChild(sourcename)
  45. nodesize = doc.createElement('size')
  46. nodewidth = doc.createElement('width')
  47. nodewidth.appendChild(doc.createTextNode(str(w)))
  48. nodesize.appendChild(nodewidth)
  49. nodeheight = doc.createElement('height')
  50. nodeheight.appendChild(doc.createTextNode(str(h)))
  51. nodesize.appendChild(nodeheight)
  52. nodedepth = doc.createElement('depth')
  53. nodedepth.appendChild(doc.createTextNode(str(d)))
  54. nodesize.appendChild(nodedepth)
  55. root.appendChild(nodesize)
  56. segname = doc.createElement("segmented")
  57. segname.appendChild(doc.createTextNode("0"))
  58. root.appendChild(segname)
  59. for (box, label) in zip(box_list, label_list):
  60. nodeobject = doc.createElement('object')
  61. nodename = doc.createElement('name')
  62. nodename.appendChild(doc.createTextNode(str(label)))
  63. nodeobject.appendChild(nodename)
  64. nodebndbox = doc.createElement('bndbox')
  65. nodex1 = doc.createElement('xmin')
  66. nodex1.appendChild(doc.createTextNode(str(box[0])))
  67. nodebndbox.appendChild(nodex1)
  68. nodey1 = doc.createElement('ymin')
  69. nodey1.appendChild(doc.createTextNode(str(box[1])))
  70. nodebndbox.appendChild(nodey1)
  71. nodex2 = doc.createElement('xmax')
  72. nodex2.appendChild(doc.createTextNode(str(box[2])))
  73. nodebndbox.appendChild(nodex2)
  74. nodey2 = doc.createElement('ymax')
  75. nodey2.appendChild(doc.createTextNode(str(box[3])))
  76. nodebndbox.appendChild(nodey2)
  77. nodeobject.appendChild(nodebndbox)
  78. root.appendChild(nodeobject)
  79. fp = open(path + filename, 'w')
  80. doc.writexml(fp, indent='\n')
  81. fp.close()
  82. def load_annoataion(p):
  83. '''
  84. load annotation from the text file
  85. :param p:
  86. :return:
  87. '''
  88. text_rects = []
  89. text_tags = []
  90. if not os.path.exists(p):
  91. return np.array(text_rects, dtype=np.float32)
  92. with open(p, 'r') as f:
  93. for line in f.readlines():
  94. x1, y1, x2, y2, x3, y3, x4, y4, label = line.split(' ')[0:9]
  95. text_poly = np.array(([x1, y1], [x2, y2], [x3, y3], [x4, y4])).astype(int)
  96. # xmin, ymin, xmax, ymax = poly2rect(text_poly)
  97. x, y, w, h = cv2.boundingRect(text_poly) #x,y为左上点坐标
  98. xmin = x
  99. ymin = y
  100. xmax = x + w
  101. ymax = y + h
  102. text_rects.append([xmin, ymin, xmax, ymax])
  103. text_tags.append(label)
  104. return np.array(text_rects, dtype=np.int32), np.array(text_tags, dtype=np.str)
  105. if __name__ == "__main__":
  106. txt_path = './txt_labels/'
  107. xml_path = './xml_labels/'
  108. img_path = './images/'
  109. txts = os.listdir(txt_path)
  110. for count, t in enumerate(txts):
  111. boxes, labels = load_annoataion(os.path.join(txt_path, t))
  112. xml_name = t.replace('.txt', '.xml')
  113. img_name = t.replace('.txt', '.png')
  114. print(img_name)
  115. img = cv2.imread(os.path.join(img_path, img_name))
  116. h, w, d = img.shape
  117. WriterXMLFiles(xml_name, xml_path, boxes, labels, w, h, d)

同理,也可以将xml格式的标签文件转化为DOTA的txt格式(以AIR-SARship数据集的标签为例)

 

  1. import os
  2. import os.path
  3. from xml.dom.minidom import parse
  4. def xml2txt(xml_path, txt_path):
  5. filenames = os.listdir(xml_path)
  6. for filename in filenames:
  7. if '.xml' in filename:
  8. file_data = ''
  9. xml_file = os.path.join(xml_path, filename)
  10. dom = parse(xml_file)
  11. root = dom.documentElement
  12. # 根据文件的树状结构,一级级找到point点所在的位置即可
  13. for obj in root.getElementsByTagName('object'):
  14. line = ['0'] * 9
  15. name = obj.getElementsByTagName('name')[0].childNodes[0].data
  16. x1, y1 = obj.getElementsByTagName('point')[0].childNodes[0].data.split(',')
  17. x2, y2 = obj.getElementsByTagName('point')[1].childNodes[0].data.split(',')
  18. x3, y3 = obj.getElementsByTagName('point')[2].childNodes[0].data.split(',')
  19. x4, y4 = obj.getElementsByTagName('point')[3].childNodes[0].data.split(',')
  20. line = x1 + y1 + ' ' + x2 + y2 + ' ' + x3 + y3 + ' ' + x4 + y4 + ' ' + name + '\n'
  21. file_data += line
  22. with open(txt_path + filename.replace('.xml', '.txt'), 'w') as fw:
  23. print('filename: ', filename)
  24. print('file_data: ', file_data)
  25. fw.write(file_data)
  26. if __name__ == "__main__":
  27. xml_path = './AIR-SARShip-2.0-xml/'
  28. # xml_path = './test_xml/'
  29. txt_path = './AIR-SARShip-2.0-txt/'
  30. xml2txt(xml_path, txt_path)

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号