caffe数据集LMDB的生成


原文链接: caffe数据集LMDB的生成

caffe 目标检测lmdb 数据集制作1 - m0_37357063的博客 - CSDN博客
caffe数据集LMDB的生成 - 啊顺 - 博客园
本文主要介绍如何在caffe框架下生成LMDB。其中包含了两个任务的LMDB生成方法,
** 一种是分类任务 imagenet
** 另一种是检测任务。 voc

voc目标检测任务

第一步 准备image文件和xml文件

对于检测任务,当然是少不了标注信息的,因此,需要准备以下几个文件:

图像文件
标签文件,是按照pascal voc格式的 xml文件,一张图像对应一个xml文件,图片名与标签文件名相同
如图所示,左边是图像文件,右图对应的xml文件

head VOCdevkit/VOC2007/ImageSets/Main/trainval.txt

000005
000007
000009
000012

head VOCdevkit/VOC2007/ImageSets/Main/train.txt
000012
000017
000023
000026

VOCdevkit/VOC2007/ImageSets/Main/val.txt
000005
000007
000009
000016

head VOCdevkit/VOC2007/ImageSets/Main/test.txt
000001
000002
000003
000004
000006

第二步 生成lmdb使用的 train.txt和test.txt

执行 ./data/VOC0712/create_list.sh 生成lmdb所使用的trainval.txt格式

#!/bin/bash

root_dir=$HOME/data/VOCdevkit ##  VOC 待训练图像文件路径
sub_dir=ImageSets/Main        ##  VOC trainval.txt 路径
bash_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"  ## 生成文件路径
for dataset in trainval test
do
  dst_file=$bash_dir/$dataset.txt
 
done

执行完脚本之后生成三个txt文件,如下:

1)test_name_size.txt每一行分为两个部分,第一部分是test图片的名字,第二部分是图像的size方便之后caffe训练的时候用作test;

2)test.txt每一行分为两个部分,第一部分是用作test的图片的路径信息和文件名,第二部分是用作test的图片的label信息文件(xml);

3)trainval.txt每一行分为两个部分,第一部分是用作trainval的图片的路径信息和文件名,第二部分是用作trainval的图片的label信息文件(xml);

首先,我们看一下tran.txt和test.txt的格式是怎样的。如图所示,每一行由2个部分组成,左边是图片的地址,右边是对应图片的xml地址,两者用空格相连。因此,知道了格式后,我们就可以生成了。那么地址是需要是怎样呢?下面我们会讲到,这个地址是一个相对地址,之后会与"create_data.sh"中的“data_root_dir”结合,生成绝对地址。

生成如下3个文件

test_name_size.txt test.txt trainval.txt

head data/VOC0712/trainval.txt
VOC2012/JPEGImages/2010_001329.jpg VOC2012/Annotations/2010_001329.xml
VOC2007/JPEGImages/009208.jpg VOC2007/Annotations/009208.xml
VOC2012/JPEGImages/2009_002254.jpg VOC2012/Annotations/2009_002254.xml
VOC2007/JPEGImages/001714.jpg VOC2007/Annotations/001714.xml
VOC2007/JPEGImages/004584.jpg VOC2007/Annotations/004584.xml
VOC2012/JPEGImages/2009_001635.jpg VOC2012/Annotations/2009_001635.xml
VOC2012/JPEGImages/2010_002625.jpg VOC2012/Annotations/2010_002625.xml
VOC2012/JPEGImages/2011_002881.jpg VOC2012/Annotations/2011_002881.xml
VOC2007/JPEGImages/001211.jpg VOC2007/Annotations/001211.xml
VOC2012/JPEGImages/2008_003519.jpg VOC2012/Annotations/2008_003519.xml

head data/VOC0712/test.txt
VOC2007/JPEGImages/000001.jpg VOC2007/Annotations/000001.xml
VOC2007/JPEGImages/000002.jpg VOC2007/Annotations/000002.xml
VOC2007/JPEGImages/000003.jpg VOC2007/Annotations/000003.xml
VOC2007/JPEGImages/000004.jpg VOC2007/Annotations/000004.xml
VOC2007/JPEGImages/000006.jpg VOC2007/Annotations/000006.xml
VOC2007/JPEGImages/000008.jpg VOC2007/Annotations/000008.xml
VOC2007/JPEGImages/000010.jpg VOC2007/Annotations/000010.xml
VOC2007/JPEGImages/000011.jpg VOC2007/Annotations/000011.xml
VOC2007/JPEGImages/000013.jpg VOC2007/Annotations/000013.xml
VOC2007/JPEGImages/000014.jpg VOC2007/Annotations/000014.xml

head data/VOC0712/test_name_size.txt

000001 500 353
000002 500 335
000003 375 500
000004 406 500
000006 375 500
000008 375 500
000010 480 354
000011 324 500
000013 375 500
000014 333 500

第三步 生成labelmap.prototxt和test_name_size.txt

首先,看一下labelmap.prototxt的格式是怎么样的。如下图所示,是有多个item组成的,label为0的item是背景,接下来就是你自己标注的label,label的编号最好连续,而且每个label对应的Name需要和xml里面的name一致。

item {
  name: "none_of_the_above"
  label: 0
  display_name: "background"
}
item {
  name: "aeroplane"
  label: 1
  display_name: "aeroplane"
}

然后再看看test_name_size.txt,如下图所示。由3列组成,第一列是图片的名称,第二、三列分别是图片的高和宽。注意,这里图片的名称没有后缀名。这个文件不知道有什么用,下面函数调用中,并没有引入这个文件。

第四步 生成LMDB

这里对Tiny-DSOD/data/VOC0712/create_data.sh进行了修改,如下所示。root_dir设置caffe的路径,这里主要是用于调用这个路径下的scripts/create_annoset.py;lmdbFile是生成LMDB的地址,而lmdbLink是这个lmdbFile的软连接。其他地方,都有注释了,应该能看懂。

cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
root_dir=$cur_dir/../..
redo=1
#data_root_dir="$HOME/data/VOCdevkit"

data_root_dir="/data/opendata/VOCdevkit"
dataset_name="VOC0712"
mapfile="$root_dir/data/$dataset_name/labelmap_voc.prototxt"
anno_type="detection"
db="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
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
cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
# caffe的路径
# root_dir=$cur_dir/../..
root_dir="/home/dengshunge/Tiny-DSOD-master"

cd $root_dir

redo=1
# VOC图像数据的根目录,与txt的文件结合
data_root_dir="/data/opendata/VOCdevkit"
# trainval.txt和test.txt的路径
txtFileDir="/home/dengshunge/Desktop/LMDB"
# LMDB存储位置
lmdbFile="/home/dengshunge/Desktop/LMDB/lmdb"
# LMDB存储位置的软连接
lmdbLink="/home/dengshunge/Desktop/LMDB/lmdbLink"
# mapfile位置
mapfile="/home/dengshunge/Desktop/LMDB/labelmap.prototxt"
# 任务类型
anno_type="detection"
# 格式
db="lmdb"
# 图片尺寸,若width,height=0,0,说明按原始图片输入尺寸,否则resize到(width,height)
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
do
  python3 $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 $txtFileDir/$subset.txt $lmdbFile/$subset"_"$db $lmdbLink
done
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
`