Python读取VOC中的xml目标框实例

2020-09-24 0 812

代码:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
# get annotation object bndbox location
import os
import cv2
try:
  import xml.etree.cElementTree as ET #解析xml的c语言版的模块
except ImportError:
  import xml.etree.ElementTree as ET
											     
##get object annotation bndbox loc start 
def GetAnnotBoxLoc(AnotPath):#AnotPath VOC标注文件路径
  tree = ET.ElementTree(file=AnotPath) #打开文件,解析成一棵树型结构
  root = tree.getroot()#获取树型结构的根
  ObjectSet=root.findall(\'object\')#找到文件中所有含有object关键字的地方,这些地方含有标注目标
  ObjBndBoxSet={} #以目标类别为关键字,目标框为值组成的字典结构
  for Object in ObjectSet:
    ObjName=Object.find(\'name\').text
    BndBox=Object.find(\'bndbox\')
    x1 = int(BndBox.find(\'xmin\').text)#-1 #-1是因为程序是按0作为起始位置的
    y1 = int(BndBox.find(\'ymin\').text)#-1
    x2 = int(BndBox.find(\'xmax\').text)#-1
    y2 = int(BndBox.find(\'ymax\').text)#-1
    BndBoxLoc=[x1,y1,x2,y2]
    if ObjName in ObjBndBoxSet:
    	ObjBndBoxSet[ObjName].append(BndBoxLoc)#如果字典结构中含有这个类别了,那么这个目标框要追加到其值的末尾
    else:
    	ObjBndBoxSet[ObjName]=[BndBoxLoc]#如果字典结构中没有这个类别,那么这个目标框就直接赋值给其值吧
  return ObjBndBoxSet
##get object annotation bndbox loc end

def display(objBox,pic):
  img = cv2.imread(pic)
  
  for key in objBox.keys():
    for i in range(len(objBox[key])):
      cv2.rectangle(img, (objBox[key][i][0],objBox[key][i][1]), (objBox[key][i][2], objBox[key][i][3]), (0, 0, 255), 2)    
      cv2.putText(img, key, (objBox[key][i][0],objBox[key][i][1]), cv2.FONT_HERSHEY_COMPLEX, 1, (255,0,0), 1)
  cv2.imshow(\'img\',img)
  cv2.imwrite(\'display.jpg\',img)
  cv2.waitKey(0)


if __name__== \'__main__\':
  pic = r\"./VOCdevkit/VOC2007/JPEGImages/000282.jpg\"
  ObjBndBoxSet=GetAnnotBoxLoc(r\"./VOCdevkit/VOC2007/Annotations/000282.xml\")
  print(ObjBndBoxSet)
  display(ObjBndBoxSet,pic)

输出结果:

{\’chair\’: [[335, 263, 484, 373]], \’person\’: [[327, 104, 476, 300], [232, 57, 357, 374], [3, 32, 199, 374], [58, 139, 296, 374]]}

图示:

Python读取VOC中的xml目标框实例

补充知识:使用python将voc类型标注xml文件对图片进行目标还原,以及批量裁剪特定类

使用标注工具如labelimg对图片物体进行voc类型标注,会生成xml文件,如何判断别人的数据集做的好不好,可以用以下代码进行目标还原。

import xml.etree.cElementTree as ET
import cv2
import os
import glob

def GetAnnotBoxLoc(AnotPath):
  tree = ET.ElementTree(file=AnotPath)
  root = tree.getroot()
  ObjectSet=root.findall(\'object\')
  ObjBndBoxSet={} 
  for Object in ObjectSet:
    ObjName=Object.find(\'name\').text
    BndBox=Object.find(\'bndbox\')
    x1 = int(BndBox.find(\'xmin\').text)
    y1 = int(BndBox.find(\'ymin\').text)
    x2 = int(BndBox.find(\'xmax\').text)
    y2 = int(BndBox.find(\'ymax\').text)
    BndBoxLoc=[x1,y1,x2,y2]
    if ObjName in ObjBndBoxSet:
    	ObjBndBoxSet[ObjName].append(BndBoxLoc)
    else:
    	ObjBndBoxSet[ObjName]=[BndBoxLoc]
  return ObjBndBoxSet

def GetAnnotName(AnotPath):
  tree = ET.ElementTree(file=AnotPath) 
  root = tree.getroot()
  path=root.find(\'path\').text
  return path

def Drawpic(xml_path,result_path):
  n = 0
  xmls = glob.glob(os.path.join(xml_path, \'*.xml\'))
  for xml in xmls:
    n = n + 1
    box=GetAnnotBoxLoc(xml)
    path=GetAnnotName(xml)
    img = cv2.imread(path)
    for classes in list(box.keys()):
      for boxes in box[classes]:
        if classes == \"bad1\":
          cv2.rectangle(img,(int(boxes[0]),int(boxes[1])),(int(boxes[2]),int(boxes[3])),(255,0,0),3) #blue
        if classes == \"bad2\":
          cv2.rectangle(img,(int(boxes[0]),int(boxes[1])),(int(boxes[2]),int(boxes[3])),(0,255,0),3) #green
        if classes == \"bad3\":
          cv2.rectangle(img,(int(boxes[0]),int(boxes[1])),(int(boxes[2]),int(boxes[3])),(0,0,255),3) #red
    cv2.imwrite(result_path+\"/\"+str(n)+\"_result.jpg\", img)
    print(path,\"还原成功\")

Drawpic(\"/home/wxy/Dashboard/dataset/VOCdevkit/VOC2012/Annotations\",\"/home/wxy/Dashboard/dataset/VOCdevkit/VOC2012/test\")

使用labelimg对图像进行标注,folder目录需要修改一下

import xml.etree.ElementTree as ET
import os

for i in os.listdir(\'/home/wxy/Dashboard/dataset/VOCdevkit/VOC2012/Annotations\'):
  tree = ET.parse(\'/home/wxy/Dashboard/dataset/VOCdevkit/VOC2012/Annotations\'+\'/\'+i)
  root = tree.getroot()
  print(root.find(\'folder\').text)
  root.find(\'folder\').text = \'VOC2012\'
  print(root.find(\'folder\').text)
  tree.write(\'/home/wxy/Dashboard/dataset/VOCdevkit/VOC2012/Annotations\'+\'/\'+i)

批量裁剪特定类,xml.dom.minidom好像比xml.etree.cElementTree好用啊。

#coding=utf-8
import xml.dom.minidom
import cv2
import os

for name in os.listdir(\"./Annotations/\"):
  dom=xml.dom.minidom.parse(\"./Annotations/\"+name)
  root=dom.documentElement
  object_name=root.getElementsByTagName(\'name\')
  if(object_name[0].firstChild.data == \"normal\"):
    print(name)
    xmin=root.getElementsByTagName(\'xmin\')
    ymin=root.getElementsByTagName(\'ymin\')
    xmax=root.getElementsByTagName(\'xmax\')
    ymax=root.getElementsByTagName(\'ymax\')

    x_min = int(xmin[0].firstChild.data)
    y_min = int(ymin[0].firstChild.data)
    x_max = int(xmax[0].firstChild.data)
    y_max = int(ymax[0].firstChild.data)

    img=cv2.imread(\"./JPEGImages/\"+name[:-4]+\".jpg\")
    cropped=img[y_min:y_max,x_min:x_max]
    cv2.imwrite(\"./cut_jpg/\"+name[:-4]+\".jpg\", cropped)

以上这篇Python读取VOC中的xml目标框实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持自学编程网。

遇见资源网 Python Python读取VOC中的xml目标框实例 http://www.ox520.com/24890.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务