我们要用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
  1. 准备好所需要的图片samples
    这一步即准备好traing_data/image/dount文件夹里的图片样本,关于这一部,因为每个人的初始样本不同,处理的方式可能也不一致。不多说了,准备好目录树中dount文件夹中的图片即可,可参考《OpenCV3编程入门》学习笔记番外篇之OpenCV-Python使用
  2. 打label
    这里介绍一个github上的开源项目labelImg, label数据保存在traing_data/labels/dount_original 文件夹中。
  3. 转换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训练自己的数据样本经验总结