自己制作VOC数据集训练SSD

一、VOC数据集格式生成

1.1 自己的VOC数据集格式

必要的文件夹

└── mydataset
    └── VOCDataset  
        ├── Annotations        #存放xml文件,与JPEGImages中的图片一一对应,解释图片的内容等等
        ├── ImageSets          #该目录下存放的都是txt文件,txt文件中每一行包含一个图片的名称,末尾会加上±1表示正负样本
        │   ├── Action
        │   ├── Layout
        │   ├── Main
        │   └── Segmentation
        ├── JPEGImages         #存放源图片
        ├── SegmentationClass  #存放的是图片,语义分割相关
        └── SegmentationObject #存放的是图片,实例分割相关

保证:JPEGImages下存放图片,Annotations下存放与图片名对应的xml文件。ImageSets/Main下的trainval.txt和test.txt存放不带有图片后缀的名字。

1.2 创建lmdb数据格式

  • 修改create_list.sh,可放在任意位置,但最好放在mydataset的目录下。
#!/bin/bash
 
root_dir= mydataset下的文件夹 ####这里改到你数据集的路径,绝对路径
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 VOCDataset ###数据集名称
  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_list.sh,运行后,会在create_list.sh同一目录上生成trainval.txt、test.txt、test_name_size.txt。

  • 修改labelmap_voc.prototxt,改为自己的label。
  • 修改create_data.sh,创建lmdb数据集。
cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
root_dir=$cur_dir/../..

cd $root_dir

redo=1
data_root_dir= mydataset的目录下
dataset_name="VOCDataset"
mapfile="$root_dir/data/mydataset/labelmap_voc.prototxt"    #修改到你保存lambelmap_voc.protxt的路径
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/mydataset/$subset.txt \     #trainval.txt和test.txt的路径。
  $data_root_dir/$dataset_name/$db/$dataset_name"_"$subset"_"$db examples/$dataset_name
done

在项目根目录下运行create_data.sh。(在根目录下运行是为了防止生成的lmdb出现no such file)。运行后,生成examples/VOCDataset/VOCDataset_trainval_lmdb和examples/VOCDataset/VOCDataset_test_lmdb。

二、lmdb数据查看

import lmdb
import caffe

env.open("./examples/VOC0712/VOC0712_trainval_lmdb")
txn = env.begin()
datum = caffe.proto.caffe_pb2.AnnotatedDatum()
for key, value in txn.cursor():
    datum.ParseFromString(value)
    label = datum.annotation_group

三、caffe-ssd数据c++接口

3.1 AnnotatedData

标注的label获取,annotated_data_layer.cpp。

  • Annotate data parameter
AnnotatedDataParameter& anno_data_param 
有以下参数可设置:
message AnnotatedDataParameter {
  // Define the sampler.
  repeated BatchSampler batch_sampler = 1;
  // Store label name and label id in LabelMap format.
  optional string label_map_file = 2;
  // If provided, it will replace the AnnotationType stored in each
  // AnnotatedDatum.
  optional AnnotatedDatum.AnnotationType anno_type = 3;
  optional int32 yolo_data_type = 4 [default = 0];
  optional float yolo_data_jitter = 5 [default = 0.3];
  optional bool train_diffcult = 6 [default = true];
  optional bool single_class =7 [default = true]; // for yolo segementation
  optional int32 seg_scales = 8 [default = 8]; // for yolo segementation
  optional int32 seg_resize_width = 9 [default = 0]; // for yolo segementation
  optional int32 seg_resize_height = 10 [default = 0]; // for yolo segementation
}
  • Annotated Datum
// Read a data point, and use it to initialize the top blob.
  AnnotatedDatum& anno_datum = *(reader_.full().peek());
  Annotated可选参数
message AnnotatedDatum {
  enum AnnotationType {
    BBOX = 0;
    BBOXandSeg = 1;
    LANE = 2;
  }
  optional Datum datum = 1;
  // If there are "rich" annotations, specify the type of annotation.
  // Currently it only supports bounding box.
  // If there are no "rich" annotations, use label in datum instead.
  optional AnnotationType type = 2;
  // Each group contains annotation for a particular class.
  repeated AnnotationGroup annotation_group = 3;
}
  • AnnotationGroup
message AnnotationGroup {
  optional int32 group_label = 1;
  repeated Annotation annotation = 2;
}

AnnotationGroup anno_group;  声明
anno_group.annotation_size;   获取大小  保存多个Annotation
  • Annotation
const Annotation& anno = anno_group.annotation(a);
const NormalizedBBox& bbox = anno.bbox();

message NormalizedBBox {
  optional float xmin = 1;
  optional float ymin = 2;
  optional float xmax = 3;
  optional float ymax = 4;
  optional int32 label = 5;
  optional bool difficult = 6;
  optional float score = 7;
  optional float size = 8;
}

3.2 blobs

可在blob.hpp和blob.cpp中查看。

blob成员变量
 protected:
  shared_ptr<SyncedMemory> data_;// 存放数据
  shared_ptr<SyncedMemory> diff_;//存放梯度
  vector<int> shape_; //存放形状
  int count_; //数据个数
  int capacity_; //数据容量

blob常用成员函数
  const Dtype* cpu_data() const; //cpu使用的数据
  void set_cpu_data(Dtype* data);//用数据块的值来blob里面的data。
  const Dtype* gpu_data() const;//返回不可更改的指针,下同
  const Dtype* cpu_diff() const;
  const Dtype* gpu_diff() const;
  Dtype* mutable_cpu_data();//返回可更改的指针,下同
  Dtype* mutable_gpu_data();
  Dtype* mutable_cpu_diff();
  Dtype* mutable_gpu_diff();
  //带mutable_开头的意味着可以对返回的指针内容进行更改,而不带mutable_开头的返回const 指针,不能对其指针的内容进行修改,
	
int offset(const int n, const int c = 0, const int h = 0,const int w = 0) const
// 通过n,c,h,w 4个参数来计算一维向量的偏移量。
 
Dtype data_at(const int n, const int c, const int h,const int w) const//通过n,c,h,w 4个参数来来获取该向量位置上的值。
 
Dtype diff_at(const int n, const int c, const int h,const int w) const//同上
 
inline const shared_ptr<SyncedMemory>& data() const {
    CHECK(data_);
    return data_;//返回数据,不能修改
  }
 
inline const shared_ptr<SyncedMemory>& diff() const {
    CHECK(diff_);
    return diff_;//返回梯度,不能修改
  }
 
Reshape(...)//reshape 有多种多态的实现,可以是四个数字,长度为四的vector,其它blob等。
 
if (count_ > capacity_) {
    capacity_ = count_;
    data_.reset(new SyncedMemory(capacity_ * sizeof(Dtype)));
    diff_.reset(new SyncedMemory(capacity_ * sizeof(Dtype)));
  }//当空间不够的时候,需要扩大容量,reset。

void Blob<Dtype>::CopyFrom(const Blob& source, bool copy_diff, bool reshape)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值