From 30cf0dd587a58744458c7cf2d3ef28e87b22b518 Mon Sep 17 00:00:00 2001 From: Ross Girshick Date: Fri, 27 Feb 2015 11:34:35 -0800 Subject: [PATCH] bug fix: 0-base sel search boxes; add special __background__ class --- datasets/imdb.py | 29 ++++++----------------------- datasets/pascal_voc.py | 40 +++++++++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/datasets/imdb.py b/datasets/imdb.py index e715952..84f973d 100644 --- a/datasets/imdb.py +++ b/datasets/imdb.py @@ -1,20 +1,3 @@ -#imdb.name = 'voc_train_2007' -#imdb.image_dir = '/work4/rbg/VOC2007/VOCdevkit/VOC2007/JPEGImages/' -#imdb.extension = '.jpg' -#imdb.image_ids = {'000001', ... } -#imdb.sizes = [numimages x 2] -#imdb.classes = {'aeroplane', ... } -#imdb.num_classes -#imdb.class_to_id -#imdb.class_ids -#imdb.eval_func = pointer to the function that evaluates detections -#imdb.roidb_func = pointer to the function that returns regions of interest - -# imdb.name -# imdb.image_index -# imdb.image_path_from_index -# imdb.classes - import os class imdb(object): @@ -51,9 +34,6 @@ class imdb(object): def roidb_handler(self, val): self._roidb_handler = val - def image_path_at(self, i): - raise NotImplementedError - @property def roidb(self): if self._roidb is not None: @@ -61,11 +41,14 @@ class imdb(object): self._roidb = self.roidb_handler() return self._roidb - def default_roidb(self): - raise NotImplementedError - @property def cache_path(self): return os.path.abspath(os.path.join( os.path.dirname(__file__), 'cache')) + + def image_path_at(self, i): + raise NotImplementedError + + def default_roidb(self): + raise NotImplementedError diff --git a/datasets/pascal_voc.py b/datasets/pascal_voc.py index 587296f..492ac92 100644 --- a/datasets/pascal_voc.py +++ b/datasets/pascal_voc.py @@ -23,7 +23,8 @@ class pascal_voc(datasets.imdb): self._devkit_path = self._get_default_path() if devkit_path is None \ else devkit_path self._base_path = os.path.join(self._devkit_path, 'VOC' + self._year) - self._classes = ('aeroplane', 'bicycle', 'bird', 'boat', + self._classes = ('__background__', # always index 0 + 'aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', @@ -35,15 +36,24 @@ class pascal_voc(datasets.imdb): self._roidb_handler = self.selective_search_roidb def image_path_at(self, i): + """ + Return the absolute path to image i in the image sequence. + """ return self.image_path_from_index(self._image_index[i]) def image_path_from_index(self, index): + """ + Construct an image path from the image's "index" identifier. + """ image_path = os.path.join(self._base_path, 'JPEGImages', index + self._image_ext) assert os.path.exists(image_path) return image_path def _load_image_set_index(self): + """ + Load the indexes listed in this dataset's image set file. + """ # Example path to image set file: # self._devkit_path + /VOCdevkit2007/VOC2007/ImageSets/Main/val.txt image_set_file = os.path.join(self._base_path, 'ImageSets', 'Main', @@ -54,6 +64,9 @@ class pascal_voc(datasets.imdb): return image_index def _get_default_path(self): + """ + Return the default path where PASCAL VOC is expected to be installed. + """ path = os.path.abspath(os.path.join( os.path.dirname(__file__), '..', 'datasets', 'VOCdevkit' + self._year)) @@ -62,7 +75,9 @@ class pascal_voc(datasets.imdb): def gt_roidb(self): """ - Return the ground-truth ROI db + Return the database of ground-truth regions of interest. + + This function loads/saves from/to a cache file to speed up future calls. """ cache_file = os.path.join(self.cache_path, self.name + '_gt_roidb.pkl') if os.path.exists(cache_file): @@ -81,6 +96,12 @@ class pascal_voc(datasets.imdb): return gt_roidb def selective_search_roidb(self): + """ + Return the database of selective search regions of interest. + Ground-truth ROIs are also included. + + This function loads/saves from/to a cache file to speed up future calls. + """ cache_file = os.path.join(self.cache_path, self.name + '_selective_search_roidb.pkl') @@ -95,7 +116,7 @@ class pascal_voc(datasets.imdb): roidb = self._merge_roidbs(gt_roidb, ss_roidb) with open(cache_file, 'wb') as fid: cPickle.dump(roidb, fid, cPickle.HIGHEST_PROTOCOL) - print 'wrote gt roidb to {}'.format(cache_file) + print 'wrote ss roidb to {}'.format(cache_file) return roidb @@ -118,7 +139,7 @@ class pascal_voc(datasets.imdb): num_images = raw_data['boxes'].ravel().shape[0] ss_roidb = [] for i in xrange(num_images): - boxes = raw_data['boxes'].ravel()[i][:, (1, 0, 3, 2)] + boxes = raw_data['boxes'].ravel()[i][:, (1, 0, 3, 2)] - 1 num_boxes = boxes.shape[0] gt_boxes = gt_roidb[i]['boxes'] gt_classes = gt_roidb[i]['gt_classes'] @@ -132,8 +153,8 @@ class pascal_voc(datasets.imdb): overlaps[I, gt_classes[argmaxes[I]]] = maxes[I] overlaps = scipy.sparse.csr_matrix(overlaps) ss_roidb.append({'boxes' : boxes, - 'gt_classes' : -np.ones((num_boxes,), - dtype=np.int32), + 'gt_classes' : np.zeros((num_boxes,), + dtype=np.int32), 'gt_overlaps' : overlaps}) return ss_roidb @@ -145,10 +166,7 @@ class pascal_voc(datasets.imdb): filename = os.path.join(self._base_path, 'Annotations', index + '.xml') # print 'Loading: {}'.format(filename) def get_data_from_tag(node, tag): - try: - return node.getElementsByTagName(tag)[0].childNodes[0].data - except: - return -1 + return node.getElementsByTagName(tag)[0].childNodes[0].data with open(filename) as f: data = minidom.parseString(f.read()) @@ -157,7 +175,7 @@ class pascal_voc(datasets.imdb): num_objs = len(objs) boxes = np.zeros((num_objs, 4), dtype=np.uint16) - gt_classes = -np.ones((num_objs), dtype=np.int32) + gt_classes = np.zeros((num_objs), dtype=np.int32) overlaps = np.zeros((num_objs, self.num_classes), dtype=np.float32) # Load object bounding boxes into a data frame. -- GitLab