Python读取VOC中的xml目标框实例
代码:
#!/usr/bin/python
#-*-coding:UTF-8-*-
#getannotationobjectbndboxlocation
importos
importcv2
try:
importxml.etree.cElementTreeasET#解析xml的c语言版的模块
exceptImportError:
importxml.etree.ElementTreeasET
##getobjectannotationbndboxlocstart
defGetAnnotBoxLoc(AnotPath):#AnotPathVOC标注文件路径
tree=ET.ElementTree(file=AnotPath)#打开文件,解析成一棵树型结构
root=tree.getroot()#获取树型结构的根
ObjectSet=root.findall('object')#找到文件中所有含有object关键字的地方,这些地方含有标注目标
ObjBndBoxSet={}#以目标类别为关键字,目标框为值组成的字典结构
forObjectinObjectSet:
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]
ifObjNameinObjBndBoxSet:
ObjBndBoxSet[ObjName].append(BndBoxLoc)#如果字典结构中含有这个类别了,那么这个目标框要追加到其值的末尾
else:
ObjBndBoxSet[ObjName]=[BndBoxLoc]#如果字典结构中没有这个类别,那么这个目标框就直接赋值给其值吧
returnObjBndBoxSet
##getobjectannotationbndboxlocend
defdisplay(objBox,pic):
img=cv2.imread(pic)
forkeyinobjBox.keys():
foriinrange(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文件,如何判断别人的数据集做的好不好,可以用以下代码进行目标还原。
importxml.etree.cElementTreeasET
importcv2
importos
importglob
defGetAnnotBoxLoc(AnotPath):
tree=ET.ElementTree(file=AnotPath)
root=tree.getroot()
ObjectSet=root.findall('object')
ObjBndBoxSet={}
forObjectinObjectSet:
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]
ifObjNameinObjBndBoxSet:
ObjBndBoxSet[ObjName].append(BndBoxLoc)
else:
ObjBndBoxSet[ObjName]=[BndBoxLoc]
returnObjBndBoxSet
defGetAnnotName(AnotPath):
tree=ET.ElementTree(file=AnotPath)
root=tree.getroot()
path=root.find('path').text
returnpath
defDrawpic(xml_path,result_path):
n=0
xmls=glob.glob(os.path.join(xml_path,'*.xml'))
forxmlinxmls:
n=n+1
box=GetAnnotBoxLoc(xml)
path=GetAnnotName(xml)
img=cv2.imread(path)
forclassesinlist(box.keys()):
forboxesinbox[classes]:
ifclasses=="bad1":
cv2.rectangle(img,(int(boxes[0]),int(boxes[1])),(int(boxes[2]),int(boxes[3])),(255,0,0),3)#blue
ifclasses=="bad2":
cv2.rectangle(img,(int(boxes[0]),int(boxes[1])),(int(boxes[2]),int(boxes[3])),(0,255,0),3)#green
ifclasses=="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目录需要修改一下
importxml.etree.ElementTreeasET
importos
foriinos.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
importxml.dom.minidom
importcv2
importos
fornameinos.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目标框实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。