最近了解了下yolov3的训练数据集部分,总结了以下操作步骤:(基于pytorch框架,请预先装好pytorch的相关组件)
1.下载ImageLabel软件对图片进行兴趣区域标记,每张图片对应一个xml文件,其中记录了w,h,xmin,ymin,xmax,ymax
2.将图片装入文件夹images、xml文件装入文件夹xmls内,将其放入yolo的data文件夹(目录)下
data文件夹下文件夹如下图片:
上述的各类文件夹(除了samples)本不是存在的,其余均需要自己创建(或者通过脚本创建),本次记录通过脚本一并自己创建。
文件夹功能介绍:
images:存放训练用图片 自己创建
ImageSets:存放test.txt、train.txt、trainval.txt、val.txt,各个txt文件中存放了训练、测试用的图片文件名。 通过脚本检测并创建
labels:存放根据xml文件中计算的参数,具体实现为voc_label.py脚本中实现,输出txt文件至该文件夹中。 自己创建
xmls:存放xml文件,用于计算labels文件夹中的txt文件 自己创建
samples:存放用于测试的图片文件,用于最后运行detect.py时用到。 默认存在
3.创建脚本文件,本次记录中将脚本创建在yolo根目录下:创建的脚本有两个,分别为voc_label.py、make_txt.py。
make_txt.py
# -*- coding:utf-8 -* import os import random import shutil # 检测文件夹ImageSets是否存在,若不存在则创建文件夹 if os.path.exists('data/ImageSets'): shutil.rmtree('data/ImageSets') os.makedirs('data/ImageSets') else: os.makedirs('data/ImageSets') trainval_percent = 0.2 train_percent = 0.8 xmlfilepath = 'data/xmls' txtsavepath = 'data/ImageSets' total_xml = os.listdir(xmlfilepath) num = len(total_xml) list = range(num) tv = int(num * trainval_percent) tr = int(tv * train_percent) trainval = random.sample(list, tv) train = random.sample(trainval, tr) ftrainval = open('data/ImageSets/trainval.txt', 'w') ftest = open('data/ImageSets/test.txt', 'w') ftrain = open('data/ImageSets/train.txt', 'w') fval = open('data/ImageSets/val.txt', 'w') for i in list: name = total_xml[i][:-4] + '\n' if i in trainval: ftrainval.write(name) if i in train: ftest.write(name) else: fval.write(name) else: ftrain.write(name) ftrainval.close() ftrain.close() fval.close() ftest.close()
voc_label.py
# -*- coding:utf-8 -* import xml.etree.ElementTree as ET import pickle import os from os import listdir, getcwd from os.path import join sets = ['train', 'test', 'val'] classes = ['CT','T'] # 在这里设置自己的各个类名称 def convert(size, box): dw = 1. / size[0] dh = 1. / size[1] x = (box[0] + box[1]) / 2.0 y = (box[2] + box[3]) / 2.0 w = box[1] - box[0] h = box[3] - box[2] x = x * dw w = w * dw y = y * dh h = h * dh return (x, y, w, h) def convert_annotation(image_id): in_file = open('data/Annotations/%s.xml' % (image_id)) out_file = open('data/labels/%s.txt' % (image_id), 'w') tree = ET.parse(in_file) root = tree.getroot() size = root.find('size') w = int(size.find('width').text) h = int(size.find('height').text) for obj in root.iter('object'): difficult = obj.find('difficult').text cls = obj.find('name').text if cls not in classes or int(difficult) == 1: continue cls_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() print(wd)
for image_set in sets: if not os.path.exists('data/labels/'): os.makedirs('data/labels/') image_ids = open('data/ImageSets/%s.txt' % (image_set)).read().strip().split() list_file = open('data/%s.txt' % (image_set), 'w') for image_id in image_ids: list_file.write('data/images/%s.jpg\n' % (image_id)) convert_annotation(image_id) list_file.close()
两个脚本中,先运行make_txt.py,再运行voc_label.py
脚本功能介绍:
make_txt.py:检测images文件夹中图片,将其名称编号放入ImageSets中的对应txt文本中。(其中可以设置自己需要的训练和验证和测试比例)
voc_label.py:对xmls文件夹中的xml文件进行处理,将其输出到labels文件中形成txt文本。 同时在data文件夹下生成train.txt、test.txt、val.txt文件,其中存放了用于训练、测试、验证的图片文件的文件路径。
以上部分便完成了数据准备工作,下面将进行yolo配置环节。
4.对yolo的配置,主要有以下几个环节:
(1)在data文件夹下加入yolo.data,yolo.names文件。
(2)在weights文件夹下加入yolo权重文件
(3)对cfg文件夹下的用到的cfg文件进行配置
(4)对train.py和detect.py脚本中的参数进行修改。
下面依次进行介绍:
(1)在data文件夹下加入yolo.data,yolo.names文件。其中classes设置为自己需要的类别
yolo.data文件中存放文件路径和类别数目信息
classes=2 train=data/train.txt valid=data/val.txt names=data/yolo.names backup=backup/
yolo.names文件中方法对应的类别名称信息
CT T
(2)在weights文件夹下加入yolo权重文件,从相关网站下载yolo的预训练权重文件,将其放入weights文件夹下。
本次记录为yolov3-tiny.conv.15文件,(训练会生成各种.pt文件,也是权重文件,将会将其用于detect脚本中)。
(3)对cfg文件夹下的用到的cfg文件进行配置,根据train.py中的参数,对相应的cfg文件进行修改。
例如本次train.py脚本中的cfg参数如下:
因此便需要对cfg文件夹中的yolov3-tiny-3cls.cfg文件进行修改。
本次修改为4处,2处filter参数、2处classes参数,其中每个filter参数为yolo标签前面的一个convolutional标签下的filter参数。
filter参数的计算方式为(类别数目+5)*3,其中的5表示置信度、x、y、w、h。
因此本次的filter设置为(2+5)*3=21。
(4)对train.py和detect.py脚本中的参数进行修改。
修改train.py和detect.py参数。yolo采用了parse对参数进行了统一修改,方便可以通过直接运行脚本文件修改其参数,本次记录为了方便,直接在脚本文件中对默认值进行修改。
train.py文件中主要修改的参数为:
--epochs 训练的轮数设置
--cfg cfg文件路径
--data yolo.data文件路径
--weights 预训练权重文件路径
具体设置如下图:
detect.py文件设置如下(主要修改了cfg参数、weight参数为训练好的best.pt参数文件、names参数):
5.运行train.py进行训练、运行detect.py进行测试检验效果。最终输出的测试结果存放在output文件夹中。
相关视频输出实时检测为下面我会进行学习的部分。