怎麼把 PASCAL VOC 2007 / 2012 資料集轉換成LMDB格式
最近在做訓練的時候遇到了做訓練集的問題,所以總結一下自己做資料集的思路與操作。ubuntu16.04.
一、VOC資料集格式:做檢測的時候會遇到,每一個圖中可能有幾個目標,每個目標都有一個位置資訊儲存到xml檔案中,如果想將此類資料做成lmdb格式,首先就是要標記影象,得到每一個圖中目標的位置資訊,標記的程式可以網上找到,標記的工作量還是很大的,這裡講做好xml檔案之後怎麼做成lmdb。
1、首先在github上下載一個caffe-ssd,然後編譯caffe-ssd,這個編譯的方法網上有很多,這裡就不多說了。編譯好之後在./data中輸入指令下載VOC0712資料集:【因為下面的兩個指令碼還呼叫了其他的Python檔案,所以還要 make pycaffe】
- wget http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar
- wget http: //host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar
- wget http: //host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar
- tar -xvf VOCtrainval_11-May -2012.
tar- tar -xvf VOCtrainval_06-Nov -2007.tar
- tar -xvf VOCtest_06-Nov -2007.tar
解壓之後如下圖所示,在VOCdevkit資料夾內有兩個資料夾,VOC2007和VOC2012,第一個資料夾是我生成的lmdb檔案。
2、建立lmdb格式的資料集
- cd caffe
- ./data/VOC0712/create_list.sh
- ./data/VOC0712/create_data.sh
下面貼出來creat_list.sh的程式碼:
- #!/bin/bash
- root_dir=####這裡改到你資料集的路徑
- 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 VOC2007 VOC2012
- do
- if [[ $dataset == "test" && $name == "VOC2012" ]]
- then
- continue
- fi
- 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
- ./caffe-ssd/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
create_data.sh下面的這個程式碼就是要做成lmdb格式的資料集了。
- cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
- root_dir=./caffe-ssd###這裡的路徑改一下,
- cd $root_dir
- redo= 1
- data_root_dir= "./caffe-ssd/data/xuelang" ###這裡的路徑改一下,
- dataset_name="VOC0712"
- mapfile= "./caffe-ssd/data/VOC0712/labelmap_xuelang.prototxt" ###這裡的路徑改一下,
然後就能看到lmdb格式的資料集就生成了。注意這裡照著博主的改法就可以了,先執行create_list.sh指令碼再執行create_data.sh指令碼,資料集要提前準備好。
- 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
- 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
如果是自己的資料集的話要先用標記的程式標記目標位置,生成xml檔案,然後按照voc資料集的格式去生成lmdb檔案。
二、圖片和label做成lmdb格式(用於圖片分類)
1、首先將同一label的train資料集放到一個資料夾內,在該資料夾內開啟terminal輸入find -name "*.jpg*" > trainval.txt,這樣就可以將該資料夾內所有的圖片全部存到txt中;
2、生成的txt中,將jpg替換成jpg 1 (1是這些圖片對應的label,中間有空格)
3、將所有的train。txt合在一起,圖片也全部放到train資料夾中,將所有的test的txt和圖片同樣操作。
4、在examples/imagenet下找到create_imagenet.sh檔案,如下,修改
- #!/usr/bin/env sh
- # Create the imagenet lmdb inputs
- # N.B. set the path to the imagenet train + val data dirs
- set -e
- EXAMPLE=examples/imagenet
- DATA=data/teeest#這裡要改成上圖的資料路徑,
- TOOLS=build/tools
VAL_DATA_ROOT=./caffe-ssd/data/teeest/val/
- TRAIN_DATA_ROOT=./caffe-ssd/data/teeest/train/
- # Set RESIZE= true to resize the images to 256x256. Leave as false if images have
- # already been resized using another tool.
- RESIZE= true ##是不是要resize
- if $RESIZE; then
- RESIZE_HEIGHT= 128
- RESIZE_WIDTH= 128
- else
- RESIZE_HEIGHT= 0
- RESIZE_WIDTH= 0
- fi
- if [ ! -d "$TRAIN_DATA_ROOT" ]; then
- echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
- echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
- "where the ImageNet training data is stored."
- exit 1
- fi
- if [ ! -d "$VAL_DATA_ROOT" ]; then
- echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
- echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
- "where the ImageNet validation data is stored."
- exit 1
- fi
- echo "Creating train lmdb..."
- GLOG_logtostderr= 1 $TOOLS/convert_imageset \
- --resize_height=$RESIZE_HEIGHT \
- --resize_width=$RESIZE_WIDTH \
- --shuffle \
- $TRAIN_DATA_ROOT \
- $DATA/train.txt \
- $EXAMPLE/ilsvrc12_train_lmdb
- echo "Creating val lmdb..."
- GLOG_logtostderr= 1 $TOOLS/convert_imageset \
- --resize_height=$RESIZE_HEIGHT \
- --resize_width=$RESIZE_WIDTH \
- --shuffle \
- $VAL_DATA_ROOT \
- $DATA/val.txt \
- $EXAMPLE/ilsvrc12_val_lmdb#儲存的路徑和名字,需要的話可以更改
- echo "Done."
5、執行這個sh檔案,就可以生成lmdb檔案了。
三、語義分割的資料集(按畫素分類)待補充,暫時還沒有用到,等用到的時候再更新吧
最近在做訓練的時候遇到了做訓練集的問題,所以總結一下自己做資料集的思路與操作。ubuntu16.04.
一、VOC資料集格式:做檢測的時候會遇到,每一個圖中可能有幾個目標,每個目標都有一個位置資訊儲存到xml檔案中,如果想將此類資料做成lmdb格式,首先就是要標記影象,得到每一個圖中目標的位置資訊,標記的程式可以網上找到,標記的工作量還是很大的,這裡講做好xml檔案之後怎麼做成lmdb。
1、首先在github上下載一個caffe-ssd,然後編譯caffe-ssd,這個編譯的方法網上有很多,這裡就不多說了。編譯好之後在./data中輸入指令下載VOC0712資料集:【因為下面的兩個指令碼還呼叫了其他的Python檔案,所以還要 make pycaffe】
- wget http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar
- wget http: //host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar
- wget http: //host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar
- tar -xvf VOCtrainval_11-May -2012.tar
- tar -xvf VOCtrainval_06-Nov -2007.tar
- tar -xvf VOCtest_06-Nov -2007.tar
解壓之後如下圖所示,在VOCdevkit資料夾內有兩個資料夾,VOC2007和VOC2012,第一個資料夾是我生成的lmdb檔案。
2、建立lmdb格式的資料集
- cd caffe
- ./data/VOC0712/create_list.sh
- ./data/VOC0712/create_data.sh
下面貼出來creat_list.sh的程式碼:
- #!/bin/bash
- root_dir=####這裡改到你資料集的路徑
- 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 VOC2007 VOC2012
- do
- if [[ $dataset == "test" && $name == "VOC2012" ]]
- then
- continue
- fi
- 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
- ./caffe-ssd/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