在上文已经成功了安装了caffe以及对faceboxes进行了复现,这次准备的是用faceboxes网络来训练自己的数据。
一、制作自己的VOC数据集
准备自己的图片,最好命名为00001.jpg的格式,这里给出python脚本重命名的代码。
import os
path = "/home/chan/Windwill/Dataset" # 你的数据集的路径
filelist = os.listdir(path)
count = 0 # 表示从哪里开始
for file in filelist:
print(file)
for file in filelist:
Olddir = os.path.join(path, file)
if os.path.isdir(Olddir):
continue
filename = os.path.splitext(file)[0]
filetype = os.path.splitext(file)[1]
# zfill(5)表示的是多少格式的,如00000
Newdir = os.path.join(path, str(count).zfill(5) + filetype)
os.rename(Olddir, Newdir)
count += 1
重命名之后,创建一个名为VOC的文件夹,VOC下一共有5个文件夹,其中需要用到的只有3个。
新建以上三个文件夹,然后在ImageSets里面,再新建Main文件夹,里面存放四个文件。
其中test.txt保存用于测试集的图片编号(如“000123”),train.txt是训练集,val.txt是验证集,trainval.txt是交叉验证集,就是训练集合验证集的总和。
接下来是图片的标注,对于目标检测来说,推荐的软件是labelmage,可以看https://github.com/tzutalin/labelImg,这里面写得很详细了,跟着下载,然后对图片的标注放在Annotatioins之后就行了。
然后把重命名完成的图片放入JPEGImages文件夹里面,用python脚本生成上述四个txt文件。
import os
import random
xmlfilepath = '/home/chan/Windwill/VOC/Annotations/'# 你的标注xml路径
saveBasePath = "/home/chan/Windwill/" # 根目录
trainval_percent = 0.90 # 训练验证集占整个数据集的比例
train_percent = 0.90 # 训练集占训练验证集的比例
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)
print("train and val size", tv)
print("traub suze", tr)
# 注意根据自己的路径更改
ftrainval = open(os.path.join(saveBasePath, 'VOC/ImageSets/Main/trainval.txt'), 'w')
ftest = open(os.path.join(saveBasePath, 'VOC/ImageSets/Main/test.txt'), 'w')
ftrain = open(os.path.join(saveBasePath, 'VOC/ImageSets/Main/train.txt'), 'w')
fval = open(os.path.join(saveBasePath, 'VOC/ImageSets/Main/val.txt'), 'w')
for i in list:
name = total_xml[i][:-4] + '\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftrain.write(name)
else:
fval.write(name)
else:
ftest.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
二、将VOC转为lmdb格式
在与VOC文件夹同级的目录下创建一个voc_to_lmdb的文件夹,里面创建两个脚本,一个是create_list.sh,另一个是create_data.sh,还有一个label文件(可以直接复制faceboxes的)
这里使用的是faceboxes自带的脚本文件,主要数修改路径。create_list.sh给出脚本:
#!/bin/bash
HOME=/home/chan # 家目录
root_dir=$HOME/Windwill # 工程根目录
sub_dir=ImageSets/Main
bash_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo $bash_dir
for dataset in trainval test
do
dst_file=$bash_dir/$dataset.txt
if [ -f $dst_file ]
then
rm -f $dst_file
fi
for name in VOC
do
echo "Create list for $name $dataset..."
dataset_file=$root_dir/$name/$sub_dir/$dataset.txt
img_file=$bash_dir/$dataset"_img.txt"
cp $dataset_file $img_file
sed -i "s/^/$name\/JPEGImages\//g" $img_file
sed -i "s/$/.jpg/g" $img_file
label_file=$bash_dir/$dataset"_label.txt"
cp $dataset_file $label_file
sed -i "s/^/$name\/Annotations\//g" $label_file
sed -i "s/$/.xml/g" $label_file
paste -d' ' $img_file $label_file >> $dst_file
rm -f $label_file
rm -f $img_file
done
# Generate image name and size infomation.
if [ $dataset == "test" ]
then
/home/chan/FaceBoxes/build/tools/get_image_size $root_dir $dst_file $bash_dir/$dataset"_name_size.txt"
fi
# Shuffle trainval file.
if [ $dataset == "trainval" ]
then
rand_file=$dst_file.random
cat $dst_file | perl -MList::Util=shuffle -e 'print shuffle(<STDIN>);' > $rand_file
mv $rand_file $dst_file
fi
done
在该目录下运行之后会生成三个txt文件,如图:
然后就是create_data.sh文件,给出脚本,同样注意修改路径
cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
root_dir=$cur_dir/..
cd $root_dir
HOME=/home/chan # 家目录
redo=1
data_root_dir="$HOME/Windwill" # 工程目录
dataset_name="Windwill"
mapfile="$data_root_dir/VOC_to_lmdb/labelmap_face.prototxt" # label路径
anno_type="detection"
db="lmdb"
min_dim=0
max_dim=0
width=0
height=0
extra_cmd="--encode-type=jpg --encoded"
if [ $redo ]
then
extra_cmd="$extra_cmd --redo"
fi
for subset in test trainval
do
# 注意这里的py是你的caffe里面的
python /home/chan/FaceBoxes/scripts/create_annoset.py --anno-type=$anno_type --label-map-file=$mapfile --min-dim=$min_dim --max-dim=$max_dim --resize-width=$width --resize-height=$height --check-label $extra_cmd $data_root_dir $data_root_dir/VOC_to_lmdb/$subset.txt $data_root_dir/$db/$dataset_name"_"$subset"_"$db examples/$dataset_name
done
运行该脚本之后,会生成lmdb格式的文件