功能:
将标注了多个类别的图像数据集转换为只包含其中一个单类的图像数据集
处理的文件目录如下:
每个DF_*文件夹中存放的内容如下:
举一个例子说明下小程序所实现的功能:
原本对DSC01045_origin.JPG图像的标注文件为DSC01045_origin.xml
DSC01045_origin.xml(包含气疤和别的目标的标注)和DSC01047_origin.xml(不包含对目标气疤的标注)的具体内容:
要求:
当输入“气疤”时,使文件夹中所有标注文件中只保留对检测目标——气疤的标注,据此修改标注文件,并另存到新的文件夹;如果原标注文件中没有气疤,则不另存到新的文件夹。然后再根据新文件夹中的标注文件,将对应的图像放到另一个新图像文件夹中。
操作:
先将所有DF_*文件夹中的标注文件和图像文件汇集到一个文件夹中,如下图
新的标注和图像文件夹如下:
具体实现代码file_neaten_according to_the_keyboard_input.py
如下:
# -*- coding: utf-8 -*-
import os
import xml.etree.ElementTree as ET
import shutil
root_path=r'E:/path/path/path/Vott的中文Voc标签/single_class_dataset_process/'
Annotations_path=root_path+'Annotations/'
Annotations_output_path=root_path+'Annotations_oneClass_output/'
JPEGImages_path=root_path+'JPEGImages/'
JPEGImages_output_path=root_path+'JPEGImages_oneClass_output/'
def get_pics_according_to_exiting_annotations_xml(path,classname):
filenames = os.listdir(path)
if len(filenames)==0:
print(Annotations_path+'中没有找到'+classname+'类的标签文件,无法创建'+classname+'类的图像集\n')
else:
print('共找到'+classname+'类的标签'+str(len(filenames))+'个')
for filename in filenames:
pic_file = JPEGImages_path+ filename.split('.')[0]+'.JPG'
pic_pathTest=JPEGImages_output_path+path.split('/')[-2]+'/'
if (os.path.exists(pic_pathTest) != True):
os.mkdir(pic_pathTest)
output_pic_file = pic_pathTest + filename.split('.')[0] + '.JPG'
shutil.copy(pic_file,output_pic_file)
print('创建了一个有%d张标注图像的'%len(os.listdir(pic_pathTest))+classname+'类数据集')
def get_one_class_annotations_xml():
print('请从【气疤】,【砂眼】,【粘砂】,【缺肉】,【多肉】,【其它】中选择要挑选的类别的名称')
className=input("你挑选的类别名称是:")
print(className)
while className not in ['气疤','砂眼','粘砂','缺肉','多肉','其它']:
print("Sorry, 输入类别错误. Enter again:")
className = input()
filenames = os.listdir(Annotations_path)
if len(filenames)==0:
print('Annotations文件夹是空的,找不到标签文件\n\n请在'+Annotations_path+'中放入标签文件')
else:
for filename in filenames:
xml_file = Annotations_path + filename
# 使用ET模块对xml文件进行解析
tree = ET.parse(xml_file)
root = tree.getroot()
for i in range(len(root)):
for obj in root.iter('object'):
for class_name in obj.findall('name'):
if class_name.text!=className:
root.remove(obj)
if len(root)!=6:
pathTest=Annotations_output_path+className+'/'
if(os.path.exists(pathTest)!=True):
os.mkdir(pathTest)
tree.write(pathTest+filename,encoding='utf-8')
get_pics_according_to_exiting_annotations_xml(pathTest,className)
if __name__ == "__main__":
get_one_class_annotations_xml()
执行结果如下: