当前位置:   article > 正文

python labelImg xml 格式的数据集解析及可视化_用python将把用labelimg标记出来的框框转换成中点的坐标、制作计数数据集

用python将把用labelimg标记出来的框框转换成中点的坐标、制作计数数据集

1、XML 格式分析

需要关注的一般只有:
filename :图片名称
size:width,heights 图片尺寸
object:图片中标注的目标,可能含有多个目标,这个xml就有2个标注目标
----- name:标注目标 类别标签 labels
----- bndbox :标注目标框 xmin ,ymin ,xmax ,ymax (左上角,右下角坐标)
在这里插入图片描述

2、可视化:把 xml 中的目标框在原图上绘制出来 ,并显示标签

原作者代码

  1. import xml.etree.ElementTree as ET # 读取xml。
  2. import os
  3. from PIL import Image,ImageDraw,ImageFont
  4. def parse_rec(filename):
  5. tree = ET.parse(filename) # 解析读取xml函数
  6. objects = []
  7. img_dir =[]
  8. for xml_name in tree.findall('filename'):
  9. img_path = os.path.join(pic_path, xml_name.text)
  10. img_dir.append(img_path)
  11. for obj in tree.findall('object'):
  12. obj_struct = {}
  13. obj_struct['name'] = obj.find('name').text
  14. obj_struct['pose'] = obj.find('pose').text
  15. obj_struct['truncated'] = int(obj.find('truncated').text)
  16. obj_struct['difficult'] = int(obj.find('difficult').text)
  17. bbox = obj.find('bndbox')
  18. obj_struct['bbox'] = [int(bbox.find('xmin').text),
  19. int(bbox.find('ymin').text),
  20. int(bbox.find('xmax').text),
  21. int(bbox.find('ymax').text)]
  22. objects.append(obj_struct)
  23. return objects,img_dir
  24. # 可视化
  25. def visualise_gt(objects,img_dir):
  26. for id,img_path in enumerate(img_dir):
  27. img = Image.open(img_path)
  28. draw = ImageDraw.Draw(img)
  29. for a in objects:
  30. xmin =int(a['bbox'][0])
  31. ymin =int(a['bbox'][1])
  32. xmax =int(a['bbox'][2])
  33. ymax =int(a['bbox'][3])
  34. label = a['name']
  35. draw.rectangle((xmin,ymin,xmax,ymax), fill=None, outline=(0,255,0),width=2)
  36. draw.text((xmin-10,ymin-15), label, fill = (0,255,0),font=font) # 利用ImageDraw的内置函数,在图片上写入文字
  37. img.show()
  38. fontPath = "C:\Windows\Fonts\Consolas\consola.ttf" # 字体路径
  39. root = 'F:/dataset/AQM'
  40. ann_path = os.path.join(root, 'Annotations') # xml文件所在路径
  41. pic_path = os.path.join(root, 'JPEGImages') # 样本图片路径
  42. font = ImageFont.truetype(fontPath, 16)
  43. for filename in os.listdir(ann_path):
  44. xml_path = os.path.join(ann_path,filename)
  45. object,img_dir = parse_rec(xml_path)
  46. visualise_gt(object,img_dir )

根据我的任务编写的代码

  1. #!/usr/bin/python
  2. # -*- coding: UTF-8 -*-
  3. #功能:根据原图和XML文件中的框,截取图片
  4. import sys
  5. import os
  6. import cv2 as cv
  7. from tqdm import tqdm
  8. try:
  9. import xml.etree.cElementTree as ET
  10. except ImportError:
  11. import xml.etree.ElementInclude as ET
  12. root = "E:\\ProjectAll\\OCLE\\DatasetOriginal\\casing_cap\\casing_cap_missing"
  13. ann_path = os.path.join(root,'Annotations') #xml文件路径
  14. pic_path = os.path.join(root,'JPEGImages') #样本图片路径
  15. save_path_root = "E:\\ProjectAll\\OCLE\\DatasetExtraction\\casing_cap" #图片保存路径
  16. process_name = 'casing_cap' #定义要处理的部件,以调用不同的处理函数
  17. def Crop_image(pic_name, img_path, label, x0, y0, x1, y1):
  18. img = cv.imread(img_path)
  19. img_crop = img[y0:y1, x0:x1] #第一个是y方向取值,第二个是x方向取值
  20. save_path = os.path.join(save_path_root, label)
  21. img_new_name = (pic_name[0:7]+'_'+str(x0)+'.jpg')
  22. save_name = os.path.join(save_path, img_new_name)
  23. print(save_name)
  24. cv.imwrite(save_name, img_crop)
  25. def split_pin_find(tree): #开口销处理函数
  26. for xml_name in tree.findall('filename'):
  27. pic_name = xml_name.text
  28. img_path = os.path.join(pic_path, pic_name)
  29. for obj in tree.findall('object'): #遍历所有object
  30. label = obj.find('name').text
  31. bbox = obj.find('bndbox')
  32. if label == 'split_pin_loose':
  33. x0 = int(bbox.find('xmin').text)
  34. y0 = int(bbox.find('ymin').text)
  35. x1 = int(bbox.find('xmax').text)
  36. y1 = int(bbox.find('ymax').text)
  37. Crop_image(pic_name, img_path, label, x0, y0, x1, y1)
  38. elif label == 'split_pin_missing':
  39. x0 = int(bbox.find('xmin').text)
  40. y0 = int(bbox.find('ymin').text)
  41. x1 = int(bbox.find('xmax').text)
  42. y1 = int(bbox.find('ymax').text)
  43. Crop_image(pic_name, img_path, label, x0, y0, x1, y1)
  44. elif label == 'split_pin_normal':
  45. x0 = int(bbox.find('xmin').text)
  46. y0 = int(bbox.find('ymin').text)
  47. x1 = int(bbox.find('xmax').text)
  48. y1 = int(bbox.find('ymax').text)
  49. Crop_image(pic_name, img_path, label, x0, y0, x1, y1)
  50. else:
  51. x0 = int(bbox.find('xmin').text)
  52. y0 = int(bbox.find('ymin').text)
  53. x1 = int(bbox.find('xmax').text)
  54. y1 = int(bbox.find('ymax').text)
  55. label = 'split_pin_otherside'
  56. Crop_image(pic_name, img_path, label, x0, y0, x1, y1)
  57. def casing_cap_find(tree): #管帽处理函数
  58. for xml_name in tree.findall('filename'):
  59. pic_name = xml_name.text
  60. img_path = os.path.join(pic_path, pic_name)
  61. for obj in tree.findall('object'): #遍历所有object
  62. label = obj.find('name').text
  63. bbox = obj.find('bndbox')
  64. if label == 'casing_cap_loose':
  65. x0 = int(bbox.find('xmin').text)
  66. y0 = int(bbox.find('ymin').text)
  67. x1 = int(bbox.find('xmax').text)
  68. y1 = int(bbox.find('ymax').text)
  69. Crop_image(pic_name, img_path, label, x0, y0, x1, y1)
  70. elif label == 'casing_cap_missing':
  71. x0 = int(bbox.find('xmin').text)
  72. y0 = int(bbox.find('ymin').text)
  73. x1 = int(bbox.find('xmax').text)
  74. y1 = int(bbox.find('ymax').text)
  75. Crop_image(pic_name, img_path, label, x0, y0, x1, y1)
  76. else:
  77. x0 = int(bbox.find('xmin').text)
  78. y0 = int(bbox.find('ymin').text)
  79. x1 = int(bbox.find('xmax').text)
  80. y1 = int(bbox.find('ymax').text)
  81. label = 'casing_cap_normal'
  82. Crop_image(pic_name, img_path, label, x0, y0, x1, y1)
  83. def parse_rec(filename):
  84. tree = ET.parse(filename)
  85. if process_name == 'split_pin':
  86. split_pin_find(tree)
  87. elif process_name == 'casing_cap':
  88. casing_cap_find(tree)
  89. def main():
  90. for filename in tqdm(os.listdir(ann_path)):
  91. xml_path = os.path.join(ann_path, filename)
  92. parse_rec(xml_path)
  93. if __name__ == '__main__':
  94. main()

 

3、对 xml 及进行操作的重要函数

官方手册
xml.etree.ElementTree 资料
Elements and Element Trees

XML是一种固有的分层数据格式,最自然的表示方法是使用树,其内元素称作子节点

通过 parse() 解析xml文本,返回根元素 tree。(一级节点Annotation)
通过对 tree 进行findall操作,可到到带有指定标签的节点(二级节点eg:filename,object)。

Element对象有以下常用属性:
1、.tag: 标签
2、.text: 去除标签,获得标签中的内容。
3、.attrib: 获取标签中的属性和属性值。
4、.findall() : 只找到带有标签的 所有节点
5、.append() : 增加新节点
6、.set():增加或者修改属性
7、.remove():删除节点

保存xml文件: ElementTree.write()

xml.dom.minidom,另一种xml的解析方式

参考:python xml 格式的数据集标注文件解析(修改、保存、删除),可视化:https://blog.csdn.net/qq_36758461/article/details/103947168?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/93127
推荐阅读
相关标签
  

闽ICP备14008679号