voc格式标签读写操作

举报
风吹稻花香 发表于 2021/10/29 22:46:41 2021/10/29
【摘要】 image.load(imagePath) imageShape = [image.height(), image.width(), 1 if image.isGrayscale() else 3] writer = PascalVocWriter...


  
  1. image.load(imagePath)
  2. imageShape = [image.height(), image.width(),
  3. 1 if image.isGrayscale() else 3]
  4. writer = PascalVocWriter(imgFolderName, imgFileName,
  5. imageShape, localImgPath=imagePath)
  6. writer.verified = self.verified
  7. for shape in shapes:
  8. points = shape['points']
  9. label = shape['label']
  10. # Add Chris
  11. difficult = int(shape['difficult'])
  12. bndbox = LabelFile.convertPoints2BndBox(points)
  13. writer.addBndBox(bndbox[0], bndbox[1], bndbox[2], bndbox[3], label, difficult)
  14. writer.save(targetFile=filename)

pascal_voc.py文件:


  
  1. #!/usr/bin/env python
  2. # -*- coding: utf8 -*-
  3. import sys
  4. from xml.etree import ElementTree
  5. from xml.etree.ElementTree import Element, SubElement
  6. from lxml import etree
  7. import codecs
  8. XML_EXT = '.xml'
  9. ENCODE_METHOD = 'utf-8'
  10. class PascalVocWriter:
  11. def __init__(self, foldername, filename, imgSize,databaseSrc='Unknown', localImgPath=None):
  12. self.foldername = foldername
  13. self.filename = filename
  14. self.databaseSrc = databaseSrc
  15. self.imgSize = imgSize
  16. self.boxlist = []
  17. self.localImgPath = localImgPath
  18. self.verified = False
  19. def prettify(self, elem):
  20. """
  21. Return a pretty-printed XML string for the Element.
  22. """
  23. rough_string = ElementTree.tostring(elem, 'utf8')
  24. root = etree.fromstring(rough_string)
  25. return etree.tostring(root, pretty_print=True, encoding=ENCODE_METHOD).replace(" ".encode(), "\t".encode())
  26. # minidom does not support UTF-8
  27. '''reparsed = minidom.parseString(rough_string)
  28. return reparsed.toprettyxml(indent="\t", encoding=ENCODE_METHOD)'''
  29. def genXML(self):
  30. """
  31. Return XML root
  32. """
  33. # Check conditions
  34. if self.filename is None or \
  35. self.foldername is None or \
  36. self.imgSize is None:
  37. return None
  38. top = Element('annotation')
  39. if self.verified:
  40. top.set('verified', 'yes')
  41. folder = SubElement(top, 'folder')
  42. folder.text = self.foldername
  43. filename = SubElement(top, 'filename')
  44. filename.text = self.filename
  45. if self.localImgPath is not None:
  46. localImgPath = SubElement(top, 'path')
  47. localImgPath.text = self.localImgPath
  48. source = SubElement(top, 'source')
  49. database = SubElement(source, 'database')
  50. database.text = self.databaseSrc
  51. size_part = SubElement(top, 'size')
  52. width = SubElement(size_part, 'width')
  53. height = SubElement(size_part, 'height')
  54. depth = SubElement(size_part, 'depth')
  55. width.text = str(self.imgSize[1])
  56. height.text = str(self.imgSize[0])
  57. if len(self.imgSize) == 3:
  58. depth.text = str(self.imgSize[2])
  59. else:
  60. depth.text = '1'
  61. segmented = SubElement(top, 'segmented')
  62. segmented.text = '0'
  63. return top
  64. def addBndBox(self, xmin, ymin, xmax, ymax, name, difficult):
  65. bndbox = {'xmin': xmin, 'ymin': ymin, 'xmax': xmax, 'ymax': ymax}
  66. bndbox['name'] = name
  67. bndbox['difficult'] = difficult
  68. self.boxlist.append(bndbox)
  69. def appendObjects(self, top):
  70. for each_object in self.boxlist:
  71. object_item = SubElement(top, 'object')
  72. name = SubElement(object_item, 'name')
  73. try:
  74. name.text = unicode(each_object['name'])
  75. except NameError:
  76. # Py3: NameError: name 'unicode' is not defined
  77. name.text = each_object['name']
  78. pose = SubElement(object_item, 'pose')
  79. pose.text = "Unspecified"
  80. truncated = SubElement(object_item, 'truncated')
  81. if int(each_object['ymax']) == int(self.imgSize[0]) or (int(each_object['ymin'])== 1):
  82. truncated.text = "1" # max == height or min
  83. elif (int(each_object['xmax'])==int(self.imgSize[1])) or (int(each_object['xmin'])== 1):
  84. truncated.text = "1" # max == width or min
  85. else:
  86. truncated.text = "0"
  87. difficult = SubElement(object_item, 'difficult')
  88. difficult.text = str( bool(each_object['difficult']) & 1 )
  89. bndbox = SubElement(object_item, 'bndbox')
  90. xmin = SubElement(bndbox, 'xmin')
  91. xmin.text = str(each_object['xmin'])
  92. ymin = SubElement(bndbox, 'ymin')
  93. ymin.text = str(each_object['ymin'])
  94. xmax = SubElement(bndbox, 'xmax')
  95. xmax.text = str(each_object['xmax'])
  96. ymax = SubElement(bndbox, 'ymax')
  97. ymax.text = str(each_object['ymax'])
  98. def save(self, targetFile=None):
  99. root = self.genXML()
  100. self.appendObjects(root)
  101. out_file = None
  102. if targetFile is None:
  103. out_file = codecs.open(
  104. self.filename + XML_EXT, 'w', encoding=ENCODE_METHOD)
  105. else:
  106. out_file = codecs.open(targetFile, 'w', encoding=ENCODE_METHOD)
  107. prettifyResult = self.prettify(root)
  108. out_file.write(prettifyResult.decode('utf8'))
  109. out_file.close()
  110. class PascalVocReader:
  111. def __init__(self, filepath):
  112. # shapes type:
  113. # [labbel, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color, difficult]
  114. self.shapes = []
  115. self.filepath = filepath
  116. self.verified = False
  117. self.pic_width=0
  118. self.pic_height=0
  119. try:
  120. self.parseXML()
  121. except Exception as e:
  122. print("parseXML error",e)
  123. def getShapes(self):
  124. return self.shapes
  125. def addShape(self, label, bndbox, difficult):
  126. xmin = int(float(bndbox.find('xmin').text))
  127. ymin = int(float(bndbox.find('ymin').text))
  128. xmax = int(float(bndbox.find('xmax').text))
  129. ymax = int(float(bndbox.find('ymax').text))
  130. points = [(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)]
  131. self.shapes.append((label, points, None, None, difficult))
  132. def parseXML(self):
  133. assert self.filepath.endswith(XML_EXT), "Unsupport file format"
  134. parser = etree.XMLParser(encoding=ENCODE_METHOD)
  135. xmltree = ElementTree.parse(self.filepath, parser=parser).getroot()
  136. file_obj=xmltree.find('filename')
  137. if file_obj is None:
  138. filename="none"
  139. else:
  140. filename = file_obj.text
  141. self.pic_width = xmltree.find('size').find('width').text
  142. self.pic_height = xmltree.find('size').find('height').text
  143. try:
  144. verified = xmltree.attrib['verified']
  145. if verified == 'yes':
  146. self.verified = True
  147. except KeyError:
  148. self.verified = False
  149. for object_iter in xmltree.findall('object'):
  150. bndbox = object_iter.find("bndbox")
  151. label = object_iter.find('name').text
  152. # Add chris
  153. difficult = False
  154. if object_iter.find('difficult') is not None:
  155. difficult = bool(int(object_iter.find('difficult').text))
  156. self.addShape(label, bndbox, difficult)
  157. return True

文章来源: blog.csdn.net,作者:AI视觉网奇,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/jacke121/article/details/121039256

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。