我们要用yolo做我们自己的objection detection,需要自己准备样本,自己训练。在训练之前,我们需要把样本转为我们需要的格式,贴标签等。这里介绍一下这部分工作。
文件目录树:
training_data
--image
--dount #保存图片的文件夹,两类的object保存在同一文件夹下
--00001.jpg
--00002.jpg
...
--00504.jpg
--labels
--dount_original
--00001.xml
--00002.xml
...
--00504.xml
--dount
--00001.txt
--00002.txt
...
--00504.txt
--dount_label.py #python程序,用于转换label格式和生成训练测试集
--train.txt #将samples分为两部分,测试集和训练集。并分别将文件的路径名保存在这两个txt中
--test.txt
- 准备好所需要的图片samples
这一步即准备好traing_data/image/dount
文件夹里的图片样本,关于这一部,因为每个人的初始样本不同,处理的方式可能也不一致。不多说了,准备好目录树中dount文件夹中的图片即可,可参考《OpenCV3编程入门》学习笔记番外篇之OpenCV-Python使用 - 打label
这里介绍一个github上的开源项目labelImg, label数据保存在traing_data/labels/dount_original
文件夹中。 - 转换label格式,并生成训练集和测试集
.xml的标签格式需要转换程yolo所需要的格式,并且要将其分出一部分作为测试集。这里写了一个python程序,仅供参考。
#!/usr/bin/env python
#coding:utf-8
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
import random
classes = ["dount", "tip"]
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('labels/dount_original/%s.xml'%(image_id)) #输入路径
out_file = open('labels/dount/%s.txt'%(image_id), 'w') #输出路径
tree=ET.parse(in_file) #得到xml树
root = tree.getroot() #得到根
size = root.find('size') #通过size标签得到尺寸信息
w = int(size.find('width').text) #分别得到照片的宽和高
h = int(size.find('height').text)
for obj in root.iter('object'): #查找到每一个标签对象
difficult = obj.find('difficult').text #获得difficult标签内容
cls = obj.find('name').text #获得name标签内容
if cls not in classes or int(difficult) == 1:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox') #获取boundbox
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') #给bb中数之间添加空格,并输出
wd = getcwd() #取得当前工作目录
if not os.path.exists('labels/dount/'): #如果不存在要输出的文件夹,则先创建
os.makedirs('labels/dount/')
image_ids = ['%05d' % m for m in range(1, 505)] #生成从1到504的数字表示样本文件名
# image_ids = open('image/dount_train.txt').read().strip().split() #获取图片序列的id
for image_id in image_ids:
convert_annotation(image_id)
random.shuffle(image_ids) #打乱文件名
train_ids = image_ids[0:384] #取前384个为训练集
train_list = open('train.txt', 'w') #打开要输出的图片路径信息
for train_id in train_ids:
train_list.write('%s/image/dount/%s.jpg\n'%(wd, train_id)) #将训练图片的路径写入文件中
train_list.close()
test_ids = image_ids[384:504] #剩余的为测试集
test_list = open('test.txt', 'w') #打开要输出的图片路径信息
for test_id in test_ids:
test_list.write('%s/image/dount/%s.jpg\n'%(wd, test_id)) #将测试图片的路径写入文件中
test_list.close()
4.这样准备工作基本就做好了,下一步就可以训练了。可参见使用YOLO训练自己的数据样本经验总结