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

所属分类: 脚本专栏 / python 阅读数: 383
收藏 0 赞 0 分享

代码:

#!/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文件对图片进行目标还原,以及批量裁剪特定类

使用标注工具如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写了一个股票提醒系统,迷你版量化系统,完美的实现了实时提醒功能,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Python绘制的二项分布概率图示例

这篇文章主要介绍了Python绘制的二项分布概率图,涉及Python基于numpy、math的数值运算及matplotlib图形绘制相关操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

Python Learning 列表的更多操作及示例代码

这篇文章主要介绍了Python Learning-列表的更多操作,需要的朋友可以参考下
收藏 0 赞 0 分享

关于python列表增加元素的三种操作方法

这篇文章主要介绍了关于python列表增加元素的几种操作方法,主要有insert方法,extend方法和append方法,每种方法给大家介绍的非常详细,需要的朋友可以参考下
收藏 0 赞 0 分享

如何在python字符串中输入纯粹的{}

这篇文章主要介绍了如何在python字符串中输入纯粹的{}以及python字符串连接的三种方法,需要的朋友可以参考下
收藏 0 赞 0 分享

浅谈Django的缓存机制

这篇文章主要介绍了浅谈Django的缓存机制,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Django 限制用户访问频率的中间件的实现

这篇文章主要介绍了Django 限制用户访问频率的中间件的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

示例详解Python3 or Python2 两者之间的差异

这篇文章主要介绍了Python3 or Python2?示例详解两者之间的差异,在本文中给大家介绍的非常详细,需要的朋友可以参考下
收藏 0 赞 0 分享

Python wxpython模块响应鼠标拖动事件操作示例

这篇文章主要介绍了Python wxpython模块响应鼠标拖动事件操作,结合实例形式分析了Python使用wxpython模块创建窗口、绑定事件及相应鼠标事件相关操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

使用Python实现一个栈判断括号是否平衡

栈(Stack)在计算机领域是一个被广泛应用的集合,栈是线性集合,访问都严格地限制在一段,叫做顶(top)。这篇文章主要介绍了使用Python实现一个栈判断括号是否平衡,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多