您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關python如何批量統計xml中各類目標的數量的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
代碼如下:
# -*- coding:utf-8 -*- import os import xml.etree.ElementTree as ET import numpy as np np.set_printoptions(suppress=True, threshold=np.nan) import matplotlib from PIL import Image def parse_obj(xml_path, filename): tree=ET.parse(xml_path+filename) objects=[] for obj in tree.findall('object'): obj_struct={} obj_struct['name']=obj.find('name').text objects.append(obj_struct) return objects def read_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] return im_info if __name__ == '__main__': xml_path='C:/Users/nansbas/Desktop/hebin/03/' filenamess=os.listdir(xml_path) filenames=[] for name in filenamess: name=name.replace('.xml','') filenames.append(name) recs={} obs_shape={} classnames=[] num_objs={} obj_avg={} for i,name in enumerate(filenames): recs[name]=parse_obj(xml_path, name+ '.xml' ) for name in filenames: for object in recs[name]: if object['name'] not in num_objs.keys(): num_objs[object['name']]=1 else: num_objs[object['name']]+=1 if object['name'] not in classnames: classnames.append(object['name']) for name in classnames: print('{}:{}個'.format(name,num_objs[name])) print('信息統計算完畢。')
補充知識:Python對目標檢測數據集xml文件操作(統計目標種類、數量、面積、比例等&修改目標名字)
1. 根據xml文件統計目標種類以及數量
# -*- coding:utf-8 -*- #根據xml文件統計目標種類以及數量 import os import xml.etree.ElementTree as ET import numpy as np np.set_printoptions(suppress=True, threshold=np.nan) import matplotlib from PIL import Image def parse_obj(xml_path, filename): tree=ET.parse(xml_path+filename) objects=[] for obj in tree.findall('object'): obj_struct={} obj_struct['name']=obj.find('name').text objects.append(obj_struct) return objects def read_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] return im_info if __name__ == '__main__': xml_path='/home/dlut/網絡/make_database/數據集——合集/VOCdevkit/VOC2018/Annotations/' filenamess=os.listdir(xml_path) filenames=[] for name in filenamess: name=name.replace('.xml','') filenames.append(name) recs={} obs_shape={} classnames=[] num_objs={} obj_avg={} for i,name in enumerate(filenames): recs[name]=parse_obj(xml_path, name+ '.xml' ) for name in filenames: for object in recs[name]: if object['name'] not in num_objs.keys(): num_objs[object['name']]=1 else: num_objs[object['name']]+=1 if object['name'] not in classnames: classnames.append(object['name']) for name in classnames: print('{}:{}個'.format(name,num_objs[name])) print('信息統計算完畢。')
2.根據xml文件統計目標的平均長度、寬度、面積以及每一個目標在原圖中的占比
# -*- coding:utf-8 -*- #統計 # 計算每一個目標在原圖中的占比 # 計算目標的平均長度、 # 計算平均寬度, # 計算平均面積、 # 計算目標平均占比 import os import xml.etree.ElementTree as ET import numpy as np #np.set_printoptions(suppress=True, threshold=np.nan) #10,000,000 np.set_printoptions(suppress=True, threshold=10000000) #10,000,000 import matplotlib from PIL import Image def parse_obj(xml_path, filename): tree = ET.parse(xml_path + filename) objects = [] for obj in tree.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) return objects def read_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] return im_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 = [] for name in filenamess: name = name.replace('.xml', '') filenames.append(name) print(filenames) recs = {} ims_info = {} obs_shape = {} classnames = [] num_objs={} obj_avg = {} for i, name in enumerate(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('正在處理信息......') for name in filenames: im_w = ims_info[name][0] im_h = ims_info[name][1] im_area = ims_info[name][2] for object in recs[name]: if object['name'] not in num_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 if not object['name'] in obs_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]) if object['name'] not in classnames: classnames.append(object['name']) # 求平均 for name in classnames: 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文件中的目標的名字, import os, sys import glob from xml.etree import ElementTree as ET # 批量讀取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') for xml in xml_list: print(xml) per = ET.parse(xml) p = per.findall('/object') for oneper in p: # 找出person節點 child = oneper.getchildren()[0] # 找出person節點的子節點 if child.text == 'PinNormal': #需要修改的名字 child.text = 'normal bolt' #修改成什么名字 if child.text == 'PinDefect': #需要修改的名字 child.text = 'defect bolt-1' #修改成什么名字 per.write(xml) print(child.tag, ':', child.text)
感謝各位的閱讀!關于“python如何批量統計xml中各類目標的數量”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。