建立自己的voc数据集_制作自己的pascal voc数据集

最近跑faster rcnn需要训练自己的数据集,那么首先要跑通一个faster rcnn模型,比如先跑通公共数据集,证明模型是没问题的。第二步就是要自己制作数据集用于训练和测试。制作自己的目标检测数据集有两种方法,第一种是自己写,第二种是把自己的数据集改成和公共数据集一样的结构。当然第二种方法更简单。会了第二种方法,再自己重头开始写数据集的时候就不会那么难受。

系统ubuntu16。假设开始之前你已经有了一个可以跑通的faster rcnn模型,需要用自己的数据集进行训练。

除去语义分割的部分,主要用到VOC2007文件夹下的Annotations文件夹、ImageSets文件件、JPEGImages文件夹。用到的目标检测voc格式大致如下:

PASCAL_VOC07

└──VOCdevkit

├ local

├ results

├ VOC2007

│ ├── Annotations

│ ├── ImageSets

│ │ └── Main

│ └── JPEGImages

└ VOCcode

Annotations文件夹存放的是xml文件,它们是一些标注信息。比如VOC数据集中000001图片的标注信息在中,中间存放的文件名,图片的长、宽、通道存放在中,0表示这张图片不用来做语义分割,每一个表示一个物体,其中表示物体名称,是拍摄角度,1表示物体被截断,0表示检测难度为简单。<>>

VOC2007

000001.jpg

The VOC2007 Database

PASCAL VOC2007

flickr

341012865

Fried Camels

Jinky the Fruit Bat

353

500

3

0

dog

Left

1

0

48

240

195

371

person

Left

1

0

8

12

352

498

最简单办法就是把自己的数据集格式改成voc的格式,最重要的,也是需要改的地方主要是、以及中的和。这些修改可以使用标注工具label me完成。label me可以选择保存为voc的xml格式。

ImageSets文件夹中只使用到Main文件夹。Main文件夹中包含一些txt文件,这些txt以A_test、A_train、A_trainval命名。表示test/train/trainval有哪些图片,test/train/trainval的图片是否有A类。比如在A_test.txt中,000001 -1表示000001 图片属于test,-1表示000001 图片中没有A类。

000001 -1

000002 -1

000003 -1

......

可以写个python小程序把已有的xml信息做成符合A_test.txt、A_train.txt、A_trainval.txt、B_test.txt、B_train.txt、B_trainval.txt的格式。假设已经制作好了voc格式的标注信息,并且放在path下,简单假设只有A、B、C3个类。首先把它们存到不同的list中。

import os

import xml.etree.cElementTree as ET

A , B , C = [] ,[] , []

for file in os.listdir(path):

tree = ET.parse(os.path.join(path , file))

root = tree.getroot()

for obj in root.findall('object'):

name = obj.find('name').text

if name == 'A':

file = root.find('path').text

file = file.split("\\")

file = file[-1][:-4]

A.append(file)

elif name == 'B':

file = root.find('path').text

file = file.split("\\")

file = file[-1][:-4]

B.append(file)

elif name == 'C':

file = root.find('path').text

file = file.split("\\")

file = file[-1][:-4]

C.append(file)

剩下的是随机将数据集分成train和test,还有一些txt的操作,这些操作和你的数据集有关,代码需要根据自己的数据集来写。上面完成了A_test.txt、A_train.txt、A_trainval.txt的制作。

JPEGImages文件夹中存放的都是图片文件,没什么好说的,把自己的图片放在JPEGImages文件夹中就行。

现在你的voc数据集就制作完成了。

制作完数据集还需要相应的修改代码。如果你的数据集少,没有办法分成train、val、test三部分,可以只分成train和test两部分,factory.py中有一段代码

# Set up voc__

for year in ['2007', '2012']:

for split in ['train', 'val', 'trainval', 'test']:

name = 'voc_{}_{}'.format(year, split)

__sets[name] = (lambda split=split, year=year: pascal_voc(split, year))

pascal_voc(split, year)生成了pascal_voc子类,在pascal_voc.py文件中根据实际情况需要修改pascal_voc构造函数的路径以及类别。

class pascal_voc(imdb):

def __init__(self, image_set, year, devkit_path=None):

imdb.__init__(self, 'voc_' + year + '_' + image_set)

self._year = year

self._image_set = image_set

self._devkit_path = self._get_default_path() if devkit_path is None else devkit_path

self._data_path = os.path.join(self._devkit_path, 'VOC' + self._year)

self._classes = ('__background__', # always index 0

'aeroplane', 'bicycle', 'bird', 'boat',

'bottle', 'bus', 'car', 'cat', 'chair',

'cow', 'diningtable', 'dog', 'horse',

'motorbike', 'person', 'pottedplant',

'sheep', 'sofa', 'train', 'tvmonitor')

#balabala....

pascalvoc('train', '2007')表示生成pascal voc2007格式的训练数据集,pascalvoc('test', '2007')表示生成pascal voc2007格式的测试数据集。同时,如果你的数据集只有训练和测试集,ImageSets/Main中的txt文件就不再是一个类有3个txt,而是只有A_train.txt和A_test.txt。所以制作txt的代码也需要修改。

上面基本是跑通自己的目标检测数据集需要修改的地方,如果已经有一个跑通了的目标检测网络,就可以开始训练自己的数据集了。

下面记录一下关于数据集代码的调用关系,实在是太复杂了。

从开始的imdb, roidb, ratio_list, ratio_index = combined_roidb(imdb_name)

在get_roidb函数中,首先用到datasets/factory.py的get_imdb函数,get_imdb函数返回相应的pascalvoc('xxx', 'yyyy')的pascalvoc类(imdb基类)。接着get_training_roidb函数从image database获得roi database

然后filter_roidb函数去除没有bounding box的图片,接着rank_roidb_ratio函数按照roi的长宽比排序。

所以返回的imdb, roidb, ratio_list, ratio_index表示image database、roi database、长宽比、长宽比索引。

之后就是写一个torch.utils.data.Dataset子类,将roi database包装成pytorch的Dataset的抽象类。还要写个torch.utils.data.sampler.Sampler基础采样器的子类,控制数据集的采样方式,注意的是如果数据集大小不能被batch_size整除的时候,余下部分的处理。最后,有了上面两个子类,就可以使用torch.utils.data.DataLoader加载数据了。总结就是重写了classtorch.utils.data.DataLoader(dataset, batch_size=1, shuffle=False, sampler=None, num_workers=0,......)的dataset和sampler。

剩下的就是送入网络训练。

你可能感兴趣的:(建立自己的voc数据集)