基于caffe的SSD目标检测——训练集生成和lmdb文件的制作
基于caffe的SSD目标检测——训练集生成和lmdb文件的制作
https://github.com/weiliu89/caffe/tree/ssd
一级目录:
build cmake CONTRIBUTING.md data docker examples INSTALL.md LICENSE Makefile.config matlab python scripts tools
caffe.cloc CMakeLists.txt CONTRIBUTORS.md distribute docs include jobs Makefile Makefile.config.example models README.md src
data目录中包含对数据集的生成脚本,进入打他中的VOC0712文件夹,文件如下:
coco_voc_map.txt create_data.sh create_list.sh labelmap_voc.prototxt
其中coco_voc_map.txt是mscoco数据集与voc数据集的类别对应关系。create_list.sh 是生成训练数据和样本对list的txt文件。create_data.sh是用来根据list生成trainval和test的lmdb文件的脚本。labelmap_voc.prototxt是VOC数据集的labelmap,即类别与名称的对应关系,是以prototxt的形式写成的,形式如下:
item {
name: "none_of_the_above"
label: 0
display_name: "background"
}
item {
name: "aeroplane"
label: 1
display_name: "aeroplane"
}
item {
name: "bicycle"
label: 2
display_name: "bicycle"
}
item {
name: "bird"
label: 3
display_name: "bird"
}
下面详细分析一下create_list.sh文件的操作:
#!/bin/bash
root_dir=$HOME/data/VOCdevkit/
# $HOME是家目录,相当于将当前的home目录,如/home接在文件路径之前。
sub_dir=ImageSets/Main
# 以上是VOC数据集中的结构
bash_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# BASH_SOURCE是当前执行shell文件的所在路径,dirname显示相对于pwd的相对路径的dirname
# 上面一句得到的是bash_dir,即shell文件的绝对路径
for dataset in trainval test
# 生成两个文件,分别为trainval用来训练和test留出来做测试集
do
dst_file=$bash_dir/$dataset.txt
# 生成的trainval.txt和test.txt的路径
if [ -f $dst_file ]
# 如果要生成的txt文件已经存在, -f指的是文件是否存在,-d表示文件夹,-x表示是否存在且具有执行权限
then
rm -f $dst_file
# 如果有,先清除,重新生成
fi
for name in VOC2007 VOC2012
# 对于VOC2007和VOC2012两个数据集
do
if [[ $dataset == "test" && $name == "VOC2012" ]]
# 如果是生成test.txt,那么不用VOC2012中的数据
then
continue
fi
echo "Create list for $name $dataset..."
# print一下进程状态,name 和 dataset 分别为VOC的数据集和trainval/test
dataset_file=$root_dir/$name/$sub_dir/$dataset.txt
echo $dataset_file
# trainval.txt和test.txt,内容是图片的数字序号,注意这里的trainval.txt或test.txt存在了ImageSets/Main下面
img_file=$bash_dir/$dataset"_img.txt"
# 生成xxx/trainval_img.txt,这个是在当前目录下
cp $dataset_file $img_file
# 把trainval.txt copy到 trainval_img.txt
sed -i "s/^/$name\/JPEGImages\//g" $img_file
# sed是替换命令,在前面添加VOC2007/JPEGImages,如VOC2007/JPEGImages/000001
sed -i "s/$/.jpg/g" $img_file
# 后面添加.jpg,得到如:VOC2007/JPEGImages/000001.jpg,即VOC数据集中的相对路径
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
# 此段同上,得到xml文件的路径,如VOC2007/Annotations/000001.xml
paste -d' ' $img_file $label_file >> $dst_file
# 将上面的两个trainval_img.txt和trainval_label.txt合并成一个文件,即当前目录下的trainval.txt
rm -f $label_file
rm -f $img_file
# 删掉两个临时文件,img和label
done
# Generate image name and size infomation.
if [ $dataset == "test" ]
then
$bash_dir/../../build/tools/get_image_size $root_dir $dst_file $bash_dir/$dataset"_name_size.txt"
# 对于测试集的数据,生成实际的size文件,利用build/tools中的get_image_size
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
生成好trainval.txt和test.txt之后,就可以根据这个路径把xml和jpg文件做成lmdb文件了,即create_data.sh的操作:
cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
# bash的绝对路径
root_dir=$cur_dir/../..
# bash是存放在~cafferoot~/data/VOC0712下,所以向上两级就是cafferoot
cd $root_dir
# 进入cafferoot目录
redo=1
# 是否重新生成lmdb
# data_root_dir="$HOME/data/VOCdevkit"
data_root_dir="/data/datasets/VOCdevkit"
dataset_name="VOC0712"
mapfile="$root_dir/data/$dataset_name/labelmap_voc.prototxt"
# 各种路径
anno_type="detection"
# 如果标签type是detection的话,就要读入labelmap,并用caffe转成label_map = caffe_pb2.LabelMap()
db="lmdb"
# 生成的子路径为“lmdb”
min_dim=0
max_dim=0
width=300
height=300
# 传入参数
extra_cmd="--encode-type=jpg --encoded"
if [ $redo ]
then
extra_cmd="$extra_cmd --redo"
fi
# 额外参数
for subset in test trainval
# 对trainval 和 test 分别运行create_annoset.py的脚本,该脚本对这里的参数进行解析,并调用build/tool/里的create_annoset的caffe程序,进行lmdb的生成
do
python $root_dir/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 $root_dir/data/$dataset_name/$subset.txt $data_root_dir/$dataset_name/$db/$dataset_name"_"$subset"_"$db examples/$dataset_name
done
之后的create_annoset.py的作用就是解析参数,生成命令行,并在命令行中调用caffe的函数来制作lmdb文件。
2018年8月14日16:37:52
现在的社会不适合我们了,因为我们太怀旧了。 —— 导演,贾樟柯