1、统计XML文件内标签的种类和其数量
对于自己标注的数据集,需在标注完成后需要对标注好的XML文件校验,下面是代码,只需将SrcDir换成需要统计的xml的文件夹即可。
import os
from tqdm import tqdm
import xml.dom.minidomdef ReadXml(FilePath):if os.path.exists(FilePath) is False:return Nonedom = xml.dom.minidom.parse(FilePath)root_ = dom.documentElementobject_ = root_.getElementsByTagName('object')info = []for object_1 in object_:name = object_1.getElementsByTagName("name")[0].firstChild.databndbox = object_1.getElementsByTagName("bndbox")[0]xmin = int(bndbox.getElementsByTagName("xmin")[0].firstChild.data)ymin = int(bndbox.getElementsByTagName("ymin")[0].firstChild.data)xmax = int(bndbox.getElementsByTagName("xmax")[0].firstChild.data)ymax = int(bndbox.getElementsByTagName("ymax")[0].firstChild.data)info.append([xmin, ymin, xmax, ymax, name])return infodef CountLabelKind(Path):LabelDict = {}print("Star to count label kinds....")for root, dirs, files in os.walk(Path):for file in tqdm(files):if file[-1] == 'l':Infos = ReadXml(root + "\\" + file)for Info in Infos:if Info[-1] not in LabelDict.keys():LabelDict[Info[-1]] = 1else:LabelDict[Info[-1]] += 1return dict(sorted(LabelDict.items(), key=lambda x: x[0]))if __name__ == '__main__':SrcDir = r"D:\program\数据集\自标数据集(fall-nofall)\自标数据集(fall-nofall)\标注1~1000(1)"LabelDict = CountLabelKind(SrcDir)KeyDict = sorted(LabelDict)print("%d kind labels and %d labels in total:" % (len(KeyDict), sum(LabelDict.values())))print(KeyDict)print("Label Name and it's number:")for key in KeyDict:print("%s\t: %d" % (key, LabelDict[key]))
2、运行后报错:xml.parsers.expat.ExpatError: no element found: line 1, column 0
这是因为我的数据集中有XML文件为空
解决办法:最简单就是查看你文件夹下的XML文件的大小是否为0kb,若为0kb,直接删除。
最终统计效果如下:
3、将xml格式转换为yolov5所需的txt格式
先给大家看我的目录:
注意:
①此处的xml—txt.py文件是放在datasets文件夹下的(代码中的绝对路径)。
②imges文件夹中的train目录下的每一张图片都要有相应的xml文件,若无,则手动删除该jpg文件。
train1是存放xml文件的文件夹,train是存放txt文件的文件夹。
文件代码:
import xml.etree.ElementTree as ETimport pickle
import os
from os import listdir, getcwd
from os.path import join
import globclasses = ['fall', 'no fall', 'no fall', 'nofall']def convert(size, box):dw = 1.0 / size[0]dh = 1.0 / size[1]x = (box[0] + box[1]) / 2.0y = (box[2] + box[3]) / 2.0w = box[1] - box[0]h = box[3] - box[2]x = x * dww = w * dwy = y * dhh = h * dhreturn (x, y, w, h)def convert_annotation(image_name):in_file = open('./labels/train1/' + image_name[:-3] + 'xml') # xml文件路径out_file = open('./labels/train/' + image_name[:-3] + 'txt', 'w') # 转换后的txt文件存放路径f = open('./labels/train1/' + image_name[:-3] + 'xml')xml_text = f.read()root = ET.fromstring(xml_text)f.close()size = root.find('size')w = int(size.find('width').text)h = int(size.find('height').text)for obj in root.iter('object'):cls = obj.find('name').textif cls not in classes:print(cls)continuecls_id = classes.index(cls)xmlbox = obj.find('bndbox')b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),float(xmlbox.find('ymax').text))bb = convert((w, h), b)out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')wd = getcwd()if __name__ == '__main__':for image_path in glob.glob("./images/train/*.jpg"): # 每一张图片都对应一个xml文件这里写xml对应的图片的路径image_name = image_path.split('\\')[-1]convert_annotation(image_name)
转换后的txt文件为:
我的标注标签有四个,分别对应下面这四个数字。
接下来又是漫长且易秃的环境配置之路了。