python:批量统计xml中各类目标的数量案例
之前写了一个matlab的,越用越觉得麻烦,如果不同数据集要改类别数目,而且运行速度慢。所以重新写了一个Python的,直接读取xml文件夹路径就可以,不用预先知道类别,直接能够检测出所有类别的目标名称及其对应的数量。
分享出来给大家。
代码如下:
#-*-coding:utf-8-*- importos importxml.etree.ElementTreeasET importnumpyasnp np.set_printoptions(suppress=True,threshold=np.nan) importmatplotlib fromPILimportImage defparse_obj(xml_path,filename): tree=ET.parse(xml_path+filename) objects=[] forobjintree.findall('object'): obj_struct={} obj_struct['name']=obj.find('name').text objects.append(obj_struct) returnobjects defread_image(image_path,filename): im=Image.open(image_path+filename) W=im.size[0] H=im.size[1] area=W*H im_info=[W,H,area] returnim_info if__name__=='__main__': xml_path='C:/Users/nansbas/Desktop/hebin/03/' filenamess=os.listdir(xml_path) filenames=[] fornameinfilenamess: name=name.replace('.xml','') filenames.append(name) recs={} obs_shape={} classnames=[] num_objs={} obj_avg={} fori,nameinenumerate(filenames): recs[name]=parse_obj(xml_path,name+'.xml') fornameinfilenames: forobjectinrecs[name]: ifobject['name']notinnum_objs.keys(): num_objs[object['name']]=1 else: num_objs[object['name']]+=1 ifobject['name']notinclassnames: classnames.append(object['name']) fornameinclassnames: print('{}:{}个'.format(name,num_objs[name])) print('信息统计算完毕。')
补充知识:Python对目标检测数据集xml文件操作(统计目标种类、数量、面积、比例等&修改目标名字)
1.根据xml文件统计目标种类以及数量
#-*-coding:utf-8-*- #根据xml文件统计目标种类以及数量 importos importxml.etree.ElementTreeasET importnumpyasnp np.set_printoptions(suppress=True,threshold=np.nan) importmatplotlib fromPILimportImage defparse_obj(xml_path,filename): tree=ET.parse(xml_path+filename) objects=[] forobjintree.findall('object'): obj_struct={} obj_struct['name']=obj.find('name').text objects.append(obj_struct) returnobjects defread_image(image_path,filename): im=Image.open(image_path+filename) W=im.size[0] H=im.size[1] area=W*H im_info=[W,H,area] returnim_info if__name__=='__main__': xml_path='/home/dlut/网络/make_database/数据集——合集/VOCdevkit/VOC2018/Annotations/' filenamess=os.listdir(xml_path) filenames=[] fornameinfilenamess: name=name.replace('.xml','') filenames.append(name) recs={} obs_shape={} classnames=[] num_objs={} obj_avg={} fori,nameinenumerate(filenames): recs[name]=parse_obj(xml_path,name+'.xml') fornameinfilenames: forobjectinrecs[name]: ifobject['name']notinnum_objs.keys(): num_objs[object['name']]=1 else: num_objs[object['name']]+=1 ifobject['name']notinclassnames: classnames.append(object['name']) fornameinclassnames: print('{}:{}个'.format(name,num_objs[name])) print('信息统计算完毕。')
2.根据xml文件统计目标的平均长度、宽度、面积以及每一个目标在原图中的占比
#-*-coding:utf-8-*- #统计 #计算每一个目标在原图中的占比 #计算目标的平均长度、 #计算平均宽度, #计算平均面积、 #计算目标平均占比 importos importxml.etree.ElementTreeasET importnumpyasnp #np.set_printoptions(suppress=True,threshold=np.nan)#10,000,000 np.set_printoptions(suppress=True,threshold=10000000)#10,000,000 importmatplotlib fromPILimportImage defparse_obj(xml_path,filename): tree=ET.parse(xml_path+filename) objects=[] forobjintree.findall('object'): obj_struct={} obj_struct['name']=obj.find('name').text bbox=obj.find('bndbox') obj_struct['bbox']=[int(bbox.find('xmin').text), int(bbox.find('ymin').text), int(bbox.find('xmax').text), int(bbox.find('ymax').text)] objects.append(obj_struct) returnobjects defread_image(image_path,filename): im=Image.open(image_path+filename) W=im.size[0] H=im.size[1] area=W*H im_info=[W,H,area] returnim_info if__name__=='__main__': image_path='/home/dlut/网络/make_database/数据集——合集/VOCdevkit/VOC2018/JPEGImages/' xml_path='/home/dlut/网络/make_database/数据集——合集/VOCdevkit/VOC2018/Annotations/' filenamess=os.listdir(xml_path) filenames=[] fornameinfilenamess: name=name.replace('.xml','') filenames.append(name) print(filenames) recs={} ims_info={} obs_shape={} classnames=[] num_objs={} obj_avg={} fori,nameinenumerate(filenames): print('正在处理{}.xml'.format(name)) recs[name]=parse_obj(xml_path,name+'.xml') print('正在处理{}.jpg'.format(name)) ims_info[name]=read_image(image_path,name+'.jpg') print('所有信息收集完毕。') print('正在处理信息......') fornameinfilenames: im_w=ims_info[name][0] im_h=ims_info[name][1] im_area=ims_info[name][2] forobjectinrecs[name]: ifobject['name']notinnum_objs.keys(): num_objs[object['name']]=1 else: num_objs[object['name']]+=1 #num_objs+=1 ob_w=object['bbox'][2]-object['bbox'][0] ob_h=object['bbox'][3]-object['bbox'][1] ob_area=ob_w*ob_h w_rate=ob_w/im_w h_rate=ob_h/im_h area_rate=ob_area/im_area ifnotobject['name']inobs_shape.keys(): obs_shape[object['name']]=([[ob_w, ob_h, ob_area, w_rate, h_rate, area_rate]]) else: obs_shape[object['name']].append([ob_w, ob_h, ob_area, w_rate, h_rate, area_rate]) ifobject['name']notinclassnames: classnames.append(object['name'])#求平均 fornameinclassnames: obj_avg[name]=(np.array(obs_shape[name]).sum(axis=0))/num_objs[name] print('{}的情况如下:*******\n'.format(name)) print('目标平均W={}'.format(obj_avg[name][0])) print('目标平均H={}'.format(obj_avg[name][1])) print('目标平均area={}'.format(obj_avg[name][2])) print('目标平均与原图的W比例={}'.format(obj_avg[name][3])) print('目标平均与原图的H比例={}'.format(obj_avg[name][4])) print('目标平均原图面积占比={}\n'.format(obj_avg[name][5])) print('信息统计计算完毕。')
3.修改xml文件中某个目标的名字为另一个名字
#修改xml文件中的目标的名字, importos,sys importglob fromxml.etreeimportElementTreeasET #批量读取Annotations下的xml文件 #per=ET.parse(r'C:\Users\rockhuang\Desktop\Annotations\000003.xml') xml_dir=r'/home/dlut/网络/make_database/数据集——合集/VOCdevkit/VOC2018/Annotations' xml_list=glob.glob(xml_dir+'/*.xml') forxmlinxml_list: print(xml) per=ET.parse(xml) p=per.findall('/object') foroneperinp:#找出person节点 child=oneper.getchildren()[0]#找出person节点的子节点 ifchild.text=='PinNormal':#需要修改的名字 child.text='normalbolt'#修改成什么名字 ifchild.text=='PinDefect':#需要修改的名字 child.text='defectbolt-1'#修改成什么名字 per.write(xml) print(child.tag,':',child.text)
以上这篇python:批量统计xml中各类目标的数量案例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。