Skip to content
This repository has been archived by the owner on Jul 2, 2021. It is now read-only.

add ImagenetFullBboxDataset #673

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions chainercv/datasets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
from chainercv.datasets.cub.cub_utils import cub_label_names # NOQA
from chainercv.datasets.directory_parsing_label_dataset import directory_parsing_label_names # NOQA
from chainercv.datasets.directory_parsing_label_dataset import DirectoryParsingLabelDataset # NOQA
from chainercv.datasets.imagenet.imagenet_det_bbox_dataset import ImagenetDetBboxDataset # NOQA
from chainercv.datasets.imagenet.imagenet_full_bbox_dataset import ImagenetFullBboxDataset # NOQA
from chainercv.datasets.imagenet.imagenet_loc_bbox_dataset import ImagenetLocBboxDataset # NOQA
from chainercv.datasets.imagenet.imagenet_utils import get_imagenet_full_bbox_label_names # NOQA
from chainercv.datasets.imagenet.imagenet_utils import imagenet_det_bbox_label_names # NOQA
from chainercv.datasets.imagenet.imagenet_utils import imagenet_det_synset_ids # NOQA
from chainercv.datasets.imagenet.imagenet_utils import imagenet_full_bbox_synset_ids # NOQA
from chainercv.datasets.imagenet.imagenet_utils import imagenet_loc_bbox_label_names # NOQA
from chainercv.datasets.imagenet.imagenet_utils import imagenet_loc_synset_ids # NOQA
from chainercv.datasets.mixup_soft_label_dataset import MixUpSoftLabelDataset # NOQA
from chainercv.datasets.online_products.online_products_dataset import online_products_super_label_names # NOQA
from chainercv.datasets.online_products.online_products_dataset import OnlineProductsDataset # NOQA
Expand Down
Empty file.
172 changes: 172 additions & 0 deletions chainercv/datasets/imagenet/imagenet_det_bbox_dataset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import numpy as np
import os

from chainer.dataset import download

from chainercv.chainer_experimental.datasets.sliceable import GetterDataset
from chainercv.datasets.imagenet.imagenet_utils import get_ilsvrc_devkit
from chainercv.datasets.imagenet.imagenet_utils import imagenet_det_synset_ids
from chainercv.datasets.voc.voc_utils import parse_voc_bbox_annotation
from chainercv.utils import read_image


class ImagenetDetBboxDataset(GetterDataset):

"""ILSVRC ImageNet detection dataset.

The data is distributed on the `official Kaggle page`_.

.. _`official Kaggle page`: https://www.kaggle.com/c/
imagenet-object-detection-challenge

Please refer to the readme of ILSVRC2014 dev kit for a comprehensive
documentation. Note that the detection part of ILSVRC has not changed since
2014. An overview of annotation process is described in the `paper`_.

.. _`paper`: http://ai.stanford.edu/~olga/papers/chi2014-MultiLabel.pdf

Every image in the training set has one or more image-level labels.
The image-level labels determine the full presence, partial presence or
absence of one or more object categories.
Bounding boxes are provided around instances of the present categories.

Args:
data_dir (string): Path to the root of the training data. If this is
:obj:`auto`,
:obj:`$CHAINER_DATASET_ROOT/pfnet/chainercv/imagenet` is used.
split ({'train', 'val', 'val1', 'val2'}): Selects a split of the
dataset.
year ({'2013', '2014'}): Use a dataset prepared for a challenge
held in :obj:`year`. The default value is :obj:`2014`.
return_img_label (bool): If :obj:`True`, this dataset returns
image-wise labels. This consists of two arrays:
:obj:`img_label` and :obj:`img_label_type`.
use_val_blacklist (bool): If :obj:`False`, images that are
included in the blacklist are avoided when
the split is :obj:`val`. The default value is :obj:`False`.

This dataset returns the following data.

.. csv-table::
:header: name, shape, dtype, format

:obj:`img`, ":math:`(3, H, W)`", :obj:`float32`, \
"RGB, :math:`[0, 255]`"
:obj:`bbox`, ":math:`(R, 4)`", :obj:`float32`, \
":math:`(y_{min}, x_{min}, y_{max}, x_{max})`"
:obj:`label`, ":math:`(R,)`", :obj:`int32`, \
":math:`[0, \#fg\_class - 1]`"
:obj:`img_label` [#imagenet_det_1]_, ":math:`(M,)`", :obj:`int32`, \
":math:`[0, \#fg\_class - 1]`"
:obj:`img_label_type` [#imagenet_det_1]_ [#imagenet_det_2]_, \
":math:`(M,)`", :obj:`int32`, ":math:`[-1, 1]`"

.. [#imagenet_det_1] available
if :obj:`return_img_label = True`.
.. [#imagenet_det_2] :obj:`-1` means absent. :obj:`1` means present.
:obj:`0` means partially present. When a category is partially
present, the image contains at least one
instance of X, but not all instances of X may be annotated with
bounding boxes.

"""

def __init__(self, data_dir='auto', split='train', year='2014',
return_img_label=False, use_val_blacklist=False):
super(ImagenetDetBboxDataset, self).__init__()
if data_dir == 'auto':
data_dir = download.get_dataset_directory(
'pfnet/chainercv/imagenet')
get_ilsvrc_devkit()
val_blacklist_path = os.path.join(
data_dir, 'ILSVRC2014_devkit/data/',
'ILSVRC2014_det_validation_blacklist.txt')

if year not in ('2013', '2014'):
raise ValueError('\'year\' has to be either '
'\'2013\' or \'2014\'.')
self.base_dir = os.path.join(data_dir, 'ILSVRC')
imageset_dir = os.path.join(self.base_dir, 'ImageSets/DET')

if split == 'train':
img_labels = {}
for lb in range(0, 200):
with open(os.path.join(
imageset_dir, 'train_{}.txt'.format(lb + 1))) as f:
for l in f:
id_ = l.split()[0]
if 'ILSVRC2014' in id_ and year != '2014':
continue

anno_type = l.split()[1]
if id_ not in img_labels:
img_labels[id_] = []
img_labels[id_].append((lb, int(anno_type)))
self.img_labels = img_labels
self.ids = list(img_labels.keys())
self.split_type = 'train'
else:
if return_img_label:
raise ValueError('split has to be \'train\' when '
'return_img_label is True')
if use_val_blacklist:
blacklist_ids = []
else:
ids = []
with open(os.path.join(
imageset_dir, 'val.txt'.format(split))) as f:
for l in f:
id_ = l.split()[0]
ids.append(id_)
blacklist_ids = []
with open(val_blacklist_path) as f:
for l in f:
index = int(l.split()[0])
blacklist_ids.append(ids[index])

ids = []
with open(os.path.join(
imageset_dir, '{}.txt'.format(split))) as f:
for l in f:
id_ = l.split()[0]
if id_ not in blacklist_ids:
ids.append(id_)
self.ids = ids
self.split_type = 'val'

self.add_getter('img', self._get_image)
self.add_getter(('bbox', 'label'), self._get_inst_anno)
if return_img_label:
self.add_getter(
('img_label', 'img_label_type'), self._get_img_label)

def __len__(self):
return len(self.ids)

def _get_image(self, i):
img_path = os.path.join(
self.base_dir, 'Data/DET', self.split_type,
self.ids[i] + '.JPEG')
img = read_image(img_path, color=True)
return img

def _get_inst_anno(self, i):
if 'extra' not in self.ids[i]:
anno_path = os.path.join(
self.base_dir, 'Annotations/DET', self.split_type,
self.ids[i] + '.xml')
bbox, label, _ = parse_voc_bbox_annotation(
anno_path, imagenet_det_synset_ids,
skip_names_not_in_label_names=True)
else:
bbox = np.zeros((0, 4), dtype=np.float32)
label = np.zeros((0,), dtype=np.int32)
return bbox, label

def _get_img_label(self, i):
img_label = np.array([val[0] for val in self.img_labels[self.ids[i]]],
dtype=np.int32)
img_label_type = np.array(
[val[1] for val in self.img_labels[self.ids[i]]],
dtype=np.int32)
return img_label, img_label_type
125 changes: 125 additions & 0 deletions chainercv/datasets/imagenet/imagenet_full_bbox_dataset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import numpy as np
import os

from chainer.dataset import download

from chainercv.chainer_experimental.datasets.sliceable import GetterDataset
from chainercv.datasets.imagenet.imagenet_utils import \
imagenet_full_bbox_synset_ids
from chainercv.datasets.voc.voc_utils import parse_voc_bbox_annotation
from chainercv.utils import read_image


class ImagenetFullBboxDataset(GetterDataset):

"""ImageNet with bounding box annotation.

There are 3627 categories in this dataset.

Readable label names can be found by
:obj:`chainercv.datasets.get_imagenet_full_bbox_label_names`.

The data needs to be downloaded from the official page.
There are four steps to prepare data.

1. Download annotations from \
http://image-net.org/Annotation/Annotation.tar.gz.
2. Expand it under :obj:`DATA_DIR/Full/Annotation` with the following \
command.

.. code::

find -name "*.tar.gz" | while read NAME ; \\
do tar -xvf "${NAME%.tar.gz}.tar.gz" ; done

3. Download images using ImageNet API for all synset ids in \
:obj:`imagenet_full_bbox_synset_ids`. Images for each synset \
can be downloaded by a command like below. You need to register \
ImageNet website to use this API.

.. code::

wget -O Data/<id>.tar "http://www.image-net.org/download/synset? \\
wnid=<id>&username=<username>&accesskey=<key>&release=latest& \\
src=stanford

4. Expand images under :obj:`DATA_DIR/Full/Data` with the following \
command.

.. code::

find -name "*.tar" | while read NAME ; do mkdir ${NAME%.tar}; \\
mv ${NAME%.tar}.tar ${NAME%.tar}; cd ${NAME%.tar}; \\
tar -xvf ${NAME%.tar}.tar; rm ${NAME%.tar}.tar ; cd ..; done

Args:
data_dir (string): Path to the root of the data. If this is
:obj:`auto`,
:obj:`$CHAINER_DATASET_ROOT/pfnet/chainercv/imagenet` is used.
return_img_label (bool): If :obj:`True`, this dataset returns
image-wise labels.

This dataset returns the following data.

.. csv-table::
:header: name, shape, dtype, format

:obj:`img`, ":math:`(3, H, W)`", :obj:`float32`, \
"RGB, :math:`[0, 255]`"
:obj:`bbox`, ":math:`(R, 4)`", :obj:`float32`, \
":math:`(y_{min}, x_{min}, y_{max}, x_{max})`"
:obj:`label`, ":math:`(R,)`", :obj:`int32`, \
":math:`[0, \#fg\_class - 1]`"
:obj:`img_label` [#imagenet_full_1]_, ":math:`()`", :obj:`int32`, \
":math:`[0, \#fg\_class - 1]`"

.. [#imagenet_full_1] available
if :obj:`return_img_label = True`.

"""

def __init__(self, data_dir='auto',
return_img_label=False):
super(ImagenetFullBboxDataset, self).__init__()
if data_dir == 'auto':
data_dir = download.get_dataset_directory(
'pfnet/chainercv/imagenet')
self.base_dir = os.path.join(data_dir, 'Full')

self.paths = []
self.cls_names = []
self.img_paths = []
image_dir = os.path.join(self.base_dir, 'Annotation')
for cls_name in sorted(os.listdir(image_dir)):
cls_dir = os.path.join(image_dir, cls_name)
for name in sorted(os.listdir(cls_dir)):
img_path = os.path.join(
self.base_dir, 'Data', cls_name, name[:-4] + '.JPEG')
if os.path.exists(img_path):
self.paths.append(os.path.join(cls_dir, name))
self.img_paths.append(img_path)
self.cls_names.append(cls_name)

self.add_getter('img', self._get_image)
self.add_getter(('bbox', 'label'), self._get_inst_anno)
self.add_getter('img_label', self._get_img_label)
if not return_img_label:
self.keys = ('img', 'bbox', 'label')

def __len__(self):
return len(self.paths)

def _get_image(self, i):
img = read_image(self.img_paths[i], color=True)
return img

def _get_inst_anno(self, i):
bbox, label, _ = parse_voc_bbox_annotation(
self.paths[i], imagenet_full_bbox_synset_ids,
skip_names_not_in_label_names=False)
return bbox, label

def _get_img_label(self, i):
label = imagenet_full_bbox_synset_ids.index(
self.cls_names[i])
return np.array([label], dtype=np.int32)
Loading