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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。