这两天需要使用caffe框架跑实验,每次都需要把VOC格式转换成IMDB格式。今天就把转换格式的过程单独列成一个博客。
前提:配置caffe环境
1. export PYTHONPATH=/home/zhai/experiment/caffe-ssd-master/caffe/python:$PYTHONPATH
2. cd cafffe/
3. make all -j8
4. make pycaffe
首选在caffe/data中新建一个MyUAVDT
文件夹,将数据集(VOC2007格式)都放到data
中,这样有利于统一管理。
生成lmdb格式文件(caffe输入格式)
首先先把从caffe/data/VOC0712/ 以下几个文件拷贝到caffe/data/MyUAVDT
中:
一下自行修改使用
cd caffe/data
cp VOC0712/create_list.sh MyDataSet/
cp VOC0712/create_data.sh MyDataSet/
cp VOC0712/labelmap_voc.prototxt MyDataSet/
create_list.sh 是生成训练数据和样本对list的txt文件。create_data.sh是用来根据list生成trainval和test的lmdb文件的脚本。labelmap_voc.prototxt是VOC数据集的labelmap,即类别与名称的对应关系,
此时数据集的文件情况为:
更改复制过来的这三个文件。
labelmap_voc.prototxt需要依据自己的label来修改,举个例子如下:
item {
name: "none_of_the_above"
label: 0
display_name: "background"
}
item {
name: "airplane"
label: 1
display_name: "airplane"
}
item {
name: "ship"
label: 2
display_name: "ship"
}
item {
name: "storagetank"
label: 3
display_name: "storagetank"
}
item {
name: "baseballdiamond"
label: 4
display_name: "baseballdiamond"
}
item {
name: "tenniscourt"
label: 5
display_name: "tenniscourt"
}
item {
name: "basketballcourt"
label: 6
display_name: "basketballcourt"
}
item {
name: "groundtrackfield"
label: 7
display_name: "groundtrackfield"
}
item {
name: "habor"
label: 8
display_name: "habor"
}
item {
name: "bridge"
label: 9
display_name: "bridge"
}
item {
name: "vehicle"
label: 10
display_name: "vehicle"
}
create_list.sh更改形式:
#!/bin/bash root_dir=$HOME/caffe/data ## 更改你的路径 sub_dir=ImageSets/Main bash_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 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 MyDataSet ##更改成你的dataset的名称 do # if [[ $dataset == "test" && $name == "VOC2012" ]] #then # continue #fi echo "Create list for $name $dataset..." ..............(这里不用改,省略) done
下面详细分析一下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
更改之后为:
在caffe/data/MyUAVDT下执行命令
./create_list.sh
create_data.sh更改形式为:
cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
root_dir=$cur_dir/../..
cd $root_dir redo=1
data_root_dir="$HOME/caffe/data" ## 更改你的路径
dataset_name="MyDataSet" ##更改你的dataset的名称
mapfile="$root_dir/data/$dataset_name/labelmap_voc.prototxt"
...............(这里不用改,省略)
done
如我的
如果训练图像不是.jpeg或.jpg格式,还需要对上述两个文件中出现的指定的图像后缀名做一下修改,需要修改的地方不多。
在caffe/data/MyUAVDT下执行命令(执行之前,最好删掉##注释):
./create_data.sh
实验如下
其次,发现在examples
中有个与FFSSD-UAV
平级的目录MyUAVDT
里面为lmdb文件夹的超链接文件,后续训练使用
参考:https://blog.csdn.net/zxmyoung/article/details/107752387#t12
https://www.cnblogs.com/morikokyuro/p/13256710.html
https://www.cnblogs.com/crazybird123/p/9378037.html