深度学习之数据集构建----制作符合pascal VOC格式的训练和测试数据集(含源代码)
1 pascal VOC数据集格式简介
pascal VOC数据集由三个文件夹构成:JPEGImages,Annotations,ImageSets。
JPEGImages文件夹:存放用于训练和测试的所有原始图片(这里不需要区分哪些图片用于训练,哪些图片用于测试)。
Annotations文件夹:存放所有原始图片对应的标注文件(标注文件采用XML文件格式)
ImageSets文件夹:里面包含Main文件夹,在Main文件夹下存放训练与测试图片的索引文件,文件格式为txt。例如train.txt文件指定哪些图片用于训练,只记录图片的文件名;test.txt文件指定哪些图片用于测试,也只记录图片的文件名。
2 制作符合VOC格式的数据集方法
2.1 创建文件夹
例如,在D:\VOCdevkit目录下创建如下文件夹和txt文件(此时为空文件,仅用于展示文档结构)
VOC2020
- JPEGImages
- Annotations
- ImageSets
- Main
- train.txt
- test.txt
- Main
2.2 制作JPEGImages文件夹数据
将用于训练和测试的原始图片拷贝到JPEGImages文件夹下。
2.3 制作Annotations文件夹数据
利用LabelImg标注软件对JPEGImages文件夹下的图片文件进行标注,标注文件存放于Annotations文件夹下。LabelImg标注软件生成的xml标注文件与pascal voc的标注文件格式一样。
注意,在LabelImg软件中进行标注时,有些图片标注文件会出现width和height为0的异常情况(可能是因为图片格式的原因)
程序在使用自制的数据集,当遇到上面的xml文件时会提示“invalid label”(使用环境不同,提示错误也会不同),如图:
根据错误提示的xml文件名,打开编辑该文件,将对应图片的width和height手工输入即可。
2.4 制作ImageSets文件夹数据(自动生成)
下面介绍如何生成train.txt和test.txt文件,这两个文件分别指定了哪些图片文件用于训练,哪些图片文件用于测试。
为方便使用,专门编写了一个自动产生train.txt和test.txt的generate_train_test_txt.py文件,主要功能为:根据数据集,按照给定的训练样本占比,随机抽取数据集样本组成训练集和测试集。
代码如下:
"""
功能:将数据集按给定的比例划分成训练数据集和测试数据集,训练
数据集和测试数据集均从原始数据集中随机抽取
输入:数据集的路径,训练集样本个数占数据集总样本(训练+测试)的比例
输出:train.txt,test.txt #满足VOC格式要求的txt文件
使用方法: python generate_train_test_txt.py --path D:\VOCdevkit\VOC2020\JPEGImages --ratio 0.7 (举例)
"""
import os
import random
import argparse
trainFile = './train.txt'
testFile = './test.txt'
def parse_args():
parser = argparse.ArgumentParser(description='Generate train.txt and test.txt.')
parser.add_argument('--path', type=str, default='',
help="数据集路径.")
parser.add_argument('--ratio', type=float, default=0.7,
help='训练样本占比.')
args = parser.parse_args()
return args
def generate_train_test_txt(path, ratio_train_of_all):
# 获得文件夹下的所有文件名
file_list = os.listdir(path)
all_file_num = len(file_list) #文件夹下文件的数量
train_samples_num = int(all_file_num * ratio_train_of_all)
test_samples_num = all_file_num - train_samples_num
# 将文件顺序打乱
random.shuffle(file_list)
file_write_obj = open(trainFile, 'w')
# 生成train.txt
for i in range(train_samples_num):
file_name = file_list[i]
file_name = file_name.split('.')[0]
file_write_obj.writelines(file_name)
file_write_obj.writelines('\n')
file_write_obj.close()
file_write_obj = open(testFile, 'w')
# 生成test.txt
for i in range(test_samples_num):
file_name = file_list[i + train_samples_num]
file_name = file_name.split('.')[0]
file_write_obj.writelines(file_name)
file_write_obj.writelines('\n')
file_write_obj.close()
if __name__ == '__main__':
args = parse_args()
generate_train_test_txt(args.path, args.ratio)
print("train.txt and test.txt generated in current path")
按代码提示的使用方法,输入数据集的路径和训练样本数占比,程序自动在当前路径生成train.txt和test.txt文件。
将train.txt和test.txt拷贝到ImageSets文件夹下。
自动生成的train.txt文件:
3 使用自制的VOC格式数据集
这里以mxnet框架为例,简要介绍如何使用自制的VOC格式的数据集。
具体使用可以参考gluoncv详细介绍。gluoncv关于pascal voc数据集使用说明
from gluoncv import data, utils
train_dataset = data.VOCDetection(splits=[(2020, 'train'), (2020, 'train')])
test_dataset = data.VOCDetection(splits=[(2020, 'test')])
因为自制的数据集完全符合pascal voc格式,采用各深度学习框架提供的接口函数调用即可。