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

[WIP] Support Mask R-CNN w/ keypoints #810

Open
wants to merge 123 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
123 commits
Select commit Hold shift + click to select a range
b3e8ac0
[wip] add mask_rcnn
yuyu2172 Feb 12, 2019
31ed235
Merge remote-tracking branch 'yuyu2172/coco-instances-dataset' into m…
yuyu2172 Feb 12, 2019
bcd68fa
misc
yuyu2172 Feb 12, 2019
64cc16c
Merge remote-tracking branch 'origin/master' into mask-rcnn
yuyu2172 Feb 12, 2019
f1d4e46
doc
yuyu2172 Feb 13, 2019
1e10d32
remove unnecessary print
yuyu2172 Feb 13, 2019
e468545
misc
yuyu2172 Feb 13, 2019
75fb3ff
misc
yuyu2172 Feb 13, 2019
e19c8d0
COCOPointDataset
yuyu2172 Feb 14, 2019
1d97870
add vis_coco_point
yuyu2172 Feb 15, 2019
43e8acc
handle the case when #RoI is 0
yuyu2172 Feb 15, 2019
a65ec8f
Merge remote-tracking branch 'yuyu2172/point-data' into vis-coco-point
yuyu2172 Feb 16, 2019
cb2ad16
fix some bug
yuyu2172 Feb 16, 2019
a4319e0
delete mask option for MaskRCNN.prepare
yuyu2172 Feb 18, 2019
496dd93
use MultiprocessIterator
yuyu2172 Feb 18, 2019
183229c
change url link
yuyu2172 Feb 18, 2019
8417559
add eval_point_coco
yuyu2172 Feb 18, 2019
a8fcf2a
train now works
yuyu2172 Feb 18, 2019
0d9ba65
some speed up
yuyu2172 Feb 19, 2019
97497ea
reduce copy
yuyu2172 Feb 19, 2019
1e38522
delete unnecessary
yuyu2172 Feb 19, 2019
c63c306
reuse prepare function
yuyu2172 Feb 19, 2019
bcf9de7
merge
yuyu2172 Feb 19, 2019
bb8fd68
don't use instance method
yuyu2172 Feb 19, 2019
d98997c
merge master
yuyu2172 Feb 19, 2019
45e77be
delete eval_coco
yuyu2172 Feb 19, 2019
c8b08a4
speed up _segm_wrt_bbox
yuyu2172 Feb 19, 2019
9ef9564
delete unnecessary
yuyu2172 Feb 19, 2019
2e18bf6
COCOPointDataset -> COCOKeypointDataset
yuyu2172 Feb 19, 2019
847d2cb
Merge remote-tracking branch 'yuyu2172/vis-coco-point' into HEAD
yuyu2172 Feb 19, 2019
8ad8a74
vis_coco_point -> vis_keypoint_coco
yuyu2172 Feb 19, 2019
a48b2ba
change representation of coco_keypoint_names
yuyu2172 Feb 19, 2019
deb9f9c
add doc
yuyu2172 Feb 20, 2019
98301e3
add test for vis_keypoint_coco
yuyu2172 Feb 20, 2019
262f7ea
Merge remote-tracking branch 'yuyu2172/point-data' into eval-point-coco
yuyu2172 Feb 20, 2019
b63254e
change name and add test
yuyu2172 Feb 20, 2019
b1f6454
update doc
yuyu2172 Feb 20, 2019
9cc885a
use Conv2DActiv
yuyu2172 Feb 20, 2019
5ffd8b3
change interface of point/transforms
yuyu2172 Feb 21, 2019
e44e91f
Merge remote-tracking branch 'yuyu2172/change-cub' into HEAD
yuyu2172 Feb 21, 2019
45bd712
fix variable name
yuyu2172 Feb 21, 2019
2608094
change variable names
yuyu2172 Feb 21, 2019
716043e
flake8 and test
yuyu2172 Feb 21, 2019
f1b5aca
Merge branch 'point-data' into HEAD
yuyu2172 Feb 21, 2019
3320b39
fix class name
yuyu2172 Feb 21, 2019
97c3e7f
Merge remote-tracking branch 'yuyu2172/mask-rcnn' into keypoint-rcnn
yuyu2172 Feb 21, 2019
a467173
fix class name
yuyu2172 Feb 21, 2019
91b2b52
fix demo
yuyu2172 Feb 21, 2019
71576f5
Merge remote-tracking branch 'yuyu2172/mask-rcnn' into keypoint-rcnn
yuyu2172 Feb 21, 2019
8dd3706
fix demo
yuyu2172 Feb 21, 2019
7191dc0
demo works
yuyu2172 Feb 21, 2019
62cb5e8
eval
yuyu2172 Feb 21, 2019
18af5fb
flake8
yuyu2172 Feb 21, 2019
a9405fb
Merge remote-tracking branch 'yuyu2172/change-cub' into point-data
yuyu2172 Feb 21, 2019
9f4c927
delete zerograd
yuyu2172 Feb 21, 2019
7e610d4
complete graph when n_roi == 0
yuyu2172 Feb 25, 2019
b5cb93a
flake8
yuyu2172 Feb 25, 2019
7e707d8
fix
yuyu2172 Feb 25, 2019
9a26065
use bilinear interpolation with kernel size 4
yuyu2172 Mar 4, 2019
2d44d66
change mask_to_segm and divide mask loss by #RoI
yuyu2172 Mar 5, 2019
be4e8ad
use segm_size instead of mask_size
yuyu2172 Mar 5, 2019
2822789
fix mask_head
yuyu2172 Mar 6, 2019
6513e24
delete +1
yuyu2172 Mar 6, 2019
7e1e3ec
fix mask_to_segm and segm_to_mask
yuyu2172 Mar 6, 2019
c78925c
add test
yuyu2172 Mar 6, 2019
b181dfd
add mask_to_segm and segm_to_mask to doc
yuyu2172 Mar 6, 2019
f78c42d
merge
yuyu2172 Mar 6, 2019
acf73a6
add keypoint_loss
yuyu2172 Mar 6, 2019
6cf5637
wip
yuyu2172 Mar 6, 2019
c045eae
fix broken flake8
yuyu2172 Mar 7, 2019
ac18d36
fix mistake
yuyu2172 Mar 7, 2019
33a189f
Merge remote-tracking branch 'yuyu2172/point-transform' into keypoint…
yuyu2172 Mar 7, 2019
781792b
fix the order of data
yuyu2172 Mar 7, 2019
163f919
Merge branch 'point-data' into keypoint-rcnn
yuyu2172 Mar 7, 2019
c6639f7
fix assertion
yuyu2172 Mar 7, 2019
665f34b
fix
yuyu2172 Mar 7, 2019
df8c274
fix test
yuyu2172 Mar 7, 2019
f5adabc
fix test
yuyu2172 Mar 7, 2019
24492f7
filter invalid
yuyu2172 Mar 7, 2019
f922836
add balanced sampling for KeypointHead
yuyu2172 Mar 8, 2019
7ec9a18
remove invalid box
yuyu2172 Mar 8, 2019
1d6f599
multiscale training
yuyu2172 Mar 8, 2019
b8fa344
add eval_keypoint_detection_multi
yuyu2172 Mar 8, 2019
a94cca4
fix
yuyu2172 Mar 8, 2019
2b0b8a4
fix
yuyu2172 Mar 8, 2019
7f5a0b9
Merge remote-tracking branch 'yuyu2172/mask-rcnn-no-plus' into HEAD
yuyu2172 Mar 8, 2019
82e43b0
Merge remote-tracking branch 'origin/master' into mask-rcnn
yuyu2172 Mar 8, 2019
a2796c1
Merge branch 'mask-rcnn' into keypoint-rcnn
yuyu2172 Mar 8, 2019
e964fae
do not use bg sample
yuyu2172 Mar 8, 2019
afb6e2a
add shared_mem option
yuyu2172 Mar 8, 2019
3d317ba
fix
yuyu2172 Mar 10, 2019
902d090
fix
yuyu2172 Mar 10, 2019
d65f257
Merge remote-tracking branch 'yuyu2172/point-data' into HEAD
yuyu2172 Mar 10, 2019
8145849
fix order of bbox and label
yuyu2172 Mar 10, 2019
8da807e
merge
yuyu2172 Mar 10, 2019
e5c80fe
fix order
yuyu2172 Mar 10, 2019
d50227c
change order
yuyu2172 Mar 10, 2019
6c9d3bc
do not update bilinear interpolation layer
yuyu2172 Mar 10, 2019
553f901
fix reporter
yuyu2172 Mar 10, 2019
ae06789
fix ignore logic
yuyu2172 Mar 10, 2019
b0c733e
fix
yuyu2172 Mar 10, 2019
07daa2f
Merge remote-tracking branch 'origin/master' into HEAD
yuyu2172 Mar 15, 2019
80b8b6a
Head -> BboxHead
yuyu2172 Mar 15, 2019
fa96b48
merge Mask R-CNN to chainercv.links.model.fpn
yuyu2172 Mar 15, 2019
ffc87dd
fix variable names
yuyu2172 Mar 15, 2019
42ca5d2
update train_multi
yuyu2172 Mar 15, 2019
eeac6db
Mask R-CNN class
yuyu2172 Mar 15, 2019
20414c4
fix
yuyu2172 Mar 15, 2019
1c31a00
fix
yuyu2172 Mar 15, 2019
80401b1
fix tests
yuyu2172 Mar 15, 2019
0840f0c
merge
yuyu2172 Mar 15, 2019
462726f
merge to fpn
yuyu2172 Mar 15, 2019
8694df5
fix
yuyu2172 Mar 15, 2019
b3d3b4e
fix
yuyu2172 Mar 15, 2019
3abe75d
fix train script
yuyu2172 Mar 15, 2019
3ce01cb
add test
yuyu2172 Mar 15, 2019
c8a1526
doc
yuyu2172 Mar 15, 2019
3bd6f32
flake8
yuyu2172 Mar 15, 2019
fd54af2
fix doc
yuyu2172 Mar 15, 2019
a0528e9
merge
yuyu2172 Mar 15, 2019
e71c322
fix
yuyu2172 Mar 15, 2019
8c9816c
merge train
yuyu2172 Mar 15, 2019
ee08fbb
fix
yuyu2172 Mar 15, 2019
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Supported tasks:
+ Image Classification ([ResNet](examples/resnet), [SENet](examples/senet), [VGG](examples/vgg))
+ Object Detection ([tutorial](http://chainercv.readthedocs.io/en/latest/tutorial/detection.html), [Faster R-CNN](examples/faster_rcnn), [FPN](examples/fpn), [SSD](examples/ssd), [YOLO](examples/yolo))
+ Semantic Segmentation ([SegNet](examples/segnet), [PSPNet](examples/pspnet))
+ Instance Segmentation ([FCIS](examples/fcis),)
+ Instance Segmentation ([FCIS](examples/fcis), [Mask R-CNN](examples/fpn))

# Guiding Principles
ChainerCV is developed under the following three guiding principles.
Expand Down
2 changes: 2 additions & 0 deletions chainercv/datasets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
from chainercv.datasets.cityscapes.cityscapes_utils import cityscapes_semantic_segmentation_label_names # NOQA
from chainercv.datasets.coco.coco_bbox_dataset import COCOBboxDataset # NOQA
from chainercv.datasets.coco.coco_instance_segmentation_dataset import COCOInstanceSegmentationDataset # NOQA
from chainercv.datasets.coco.coco_keypoint_dataset import COCOKeypointDataset # NOQA
from chainercv.datasets.coco.coco_semantic_segmentation_dataset import COCOSemanticSegmentationDataset # NOQA
from chainercv.datasets.coco.coco_utils import coco_bbox_label_names # NOQA
from chainercv.datasets.coco.coco_utils import coco_instance_segmentation_label_names # NOQA
from chainercv.datasets.coco.coco_utils import coco_keypoint_names # NOQA
from chainercv.datasets.coco.coco_utils import coco_semantic_segmentation_label_colors # NOQA
from chainercv.datasets.coco.coco_utils import coco_semantic_segmentation_label_names # NOQA
from chainercv.datasets.cub.cub_keypoint_dataset import CUBKeypointDataset # NOQA
Expand Down
166 changes: 166 additions & 0 deletions chainercv/datasets/coco/coco_keypoint_dataset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
from collections import defaultdict
import json
import numpy as np
import os

from chainercv.chainer_experimental.datasets.sliceable import GetterDataset
from chainercv.datasets.coco.coco_utils import get_coco
from chainercv import utils


class COCOKeypointDataset(GetterDataset):

"""Keypoint dataset for `MS COCO`_.

This only returns annotation for objects categorized to the "person"
category.

.. _`MS COCO`: http://cocodataset.org/#home

Args:
data_dir (string): Path to the root of the training data. If this is
:obj:`auto`, this class will automatically download data for you
under :obj:`$CHAINER_DATASET_ROOT/pfnet/chainercv/coco`.
split ({'train', 'val'}): Select a split of the dataset.
year ({'2014', '2017'}): Use a dataset released in :obj:`year`.
use_crowded (bool): If true, use bounding boxes that are labeled as
crowded in the original annotation. The default value is
:obj:`False`.
return_area (bool): If true, this dataset returns areas of masks
around objects. The default value is :obj:`False`.
return_crowded (bool): If true, this dataset returns a boolean array
that indicates whether bounding boxes are labeled as crowded
or not. 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:`point` [#coco_point_1]_, ":math:`(R, K, 2)`", :obj:`float32`, \
":math:`(y, x)`"
:obj:`visible` [#coco_point_1]_, ":math:`(R, K)`", :obj:`bool`, \
"true when a keypoint is visible."
:obj:`label` [#coco_point_1]_, ":math:`(R,)`", :obj:`int32`, \
":math:`[0, \#fg\_class - 1]`"
:obj:`bbox` [#coco_point_1]_, ":math:`(R, 4)`", :obj:`float32`, \
":math:`(y_{min}, x_{min}, y_{max}, x_{max})`"
:obj:`area` [#coco_point_1]_ [#coco_point_2]_, ":math:`(R,)`", \
:obj:`float32`, --
:obj:`crowded` [#coco_point_3]_, ":math:`(R,)`", :obj:`bool`, --

.. [#coco_point_1] If :obj:`use_crowded = True`, :obj:`point`, \
:obj:`visible`, :obj:`bbox`, \
:obj:`label` and :obj:`area` contain crowded instances.
.. [#coco_point_2] :obj:`area` is available \
if :obj:`return_area = True`.
.. [#coco_point_3] :obj:`crowded` is available \
if :obj:`return_crowded = True`.

"""

def __init__(self, data_dir='auto', split='train', year='2017',
use_crowded=False,
return_area=False, return_crowded=False):
if split not in ['train', 'val']:
raise ValueError('Unsupported split is given.')
super(COCOKeypointDataset, self).__init__()
self.use_crowded = use_crowded
if data_dir == 'auto':
data_dir = get_coco(split, split, year, 'instances')

self.img_root = os.path.join(
data_dir, 'images', '{}{}'.format(split, year))
self.data_dir = data_dir

point_anno_path = os.path.join(
self.data_dir, 'annotations', 'person_keypoints_{}{}.json'.format(
split, year))
annos = json.load(open(point_anno_path, 'r'))

self.id_to_prop = {}
for prop in annos['images']:
self.id_to_prop[prop['id']] = prop
self.ids = sorted(list(self.id_to_prop.keys()))

self.cat_ids = [cat['id'] for cat in annos['categories']]

self.id_to_anno = defaultdict(list)
for anno in annos['annotations']:
self.id_to_anno[anno['image_id']].append(anno)

self.add_getter('img', self._get_image)
self.add_getter(
['point', 'visible', 'bbox', 'label', 'area', 'crowded'],
self._get_annotations)
keys = ('img', 'point', 'visible', 'label', 'bbox')
if return_area:
keys += ('area',)
if return_crowded:
keys += ('crowded',)
self.keys = keys

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

def _get_image(self, i):
img_path = os.path.join(
self.img_root, self.id_to_prop[self.ids[i]]['file_name'])
img = utils.read_image(img_path, dtype=np.float32, color=True)
return img

def _get_annotations(self, i):
# List[{'segmentation', 'area', 'iscrowd',
# 'image_id', 'bbox', 'category_id', 'id'}]
annotation = self.id_to_anno[self.ids[i]]
bbox = np.array([ann['bbox'] for ann in annotation],
dtype=np.float32)
if len(bbox) == 0:
bbox = np.zeros((0, 4), dtype=np.float32)
# (x, y, width, height) -> (x_min, y_min, x_max, y_max)
bbox[:, 2] = bbox[:, 0] + bbox[:, 2]
bbox[:, 3] = bbox[:, 1] + bbox[:, 3]
# (x_min, y_min, x_max, y_max) -> (y_min, x_min, y_max, x_max)
bbox = bbox[:, [1, 0, 3, 2]]

label = np.array([self.cat_ids.index(ann['category_id'])
for ann in annotation], dtype=np.int32)

area = np.array([ann['area']
for ann in annotation], dtype=np.float32)

crowded = np.array([ann['iscrowd']
for ann in annotation], dtype=np.bool)

point = np.array(
[anno['keypoints'] for anno in annotation], dtype=np.float32)
if len(point) > 0:
x = point[:, 0::3]
y = point[:, 1::3]
# 0: not labeled; 1: labeled, not inside mask;
# 2: labeled and inside mask
v = point[:, 2::3]
visible = v > 0
point = np.stack((y, x), axis=2)
else:
point = np.empty((0, 0, 2), dtype=np.float32)
visible = np.empty((0, 0), dtype=np.bool)

# Remove invisible boxes
bbox_area = np.prod(bbox[:, 2:] - bbox[:, :2], axis=1)
keep_mask = np.logical_and(bbox[:, 0] <= bbox[:, 2],
bbox[:, 1] <= bbox[:, 3])
keep_mask = np.logical_and(keep_mask, bbox_area > 0)

if not self.use_crowded:
keep_mask = np.logical_and(keep_mask, np.logical_not(crowded))

point = point[keep_mask]
visible = visible[keep_mask]
bbox = bbox[keep_mask]
label = label[keep_mask]
area = area[keep_mask]
crowded = crowded[keep_mask]
return point, visible, bbox, label, area, crowded
31 changes: 27 additions & 4 deletions chainercv/datasets/coco/coco_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
}
instances_anno_urls = {
'2014': {
'train': 'http://msvocds.blob.core.windows.net/annotations-1-0-3/'
'instances_train-val2014.zip',
'val': 'http://msvocds.blob.core.windows.net/annotations-1-0-3/'
'instances_train-val2014.zip',
'train': 'http://images.cocodataset.org/annotations/'
'annotations_trainval2014.zip',
'val': 'http://images.cocodataset.org/annotations/'
'annotations_trainval2014.zip',
'valminusminival': 'https://dl.dropboxusercontent.com/s/'
's3tw5zcg7395368/instances_valminusminival2014.json.zip',
'minival': 'https://dl.dropboxusercontent.com/s/o43o90bna78omob/'
Expand Down Expand Up @@ -442,3 +442,26 @@ def get_coco(split, img_split, year, mode):


coco_instance_segmentation_label_names = coco_bbox_label_names


coco_keypoint_names = {
0: [
'nose',
'left_eye',
'right_eye',
'left_ear',
'right_ear',
'left_shoulder',
'right_shoulder',
'left_elbow',
'right_elbow',
'left_wrist',
'right_wrist',
'left_hip',
'right_hip',
'left_knee',
'right_knee',
'left_ankle',
'right_ankle'
]
}
1 change: 1 addition & 0 deletions chainercv/evaluations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from chainercv.evaluations.eval_instance_segmentation_coco import eval_instance_segmentation_coco # NOQA
from chainercv.evaluations.eval_instance_segmentation_voc import calc_instance_segmentation_voc_prec_rec # NOQA
from chainercv.evaluations.eval_instance_segmentation_voc import eval_instance_segmentation_voc # NOQA
from chainercv.evaluations.eval_keypoint_detection_coco import eval_keypoint_detection_coco # NOQA
from chainercv.evaluations.eval_semantic_segmentation import calc_semantic_segmentation_confusion # NOQA
from chainercv.evaluations.eval_semantic_segmentation import calc_semantic_segmentation_iou # NOQA
from chainercv.evaluations.eval_semantic_segmentation import eval_semantic_segmentation # NOQA
Loading