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

Commit c490f57

Browse files
committed
merge to fpn
1 parent 0840f0c commit c490f57

File tree

12 files changed

+201
-534
lines changed

12 files changed

+201
-534
lines changed

chainercv/links/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
from chainercv.links.model.faster_rcnn.faster_rcnn_vgg import FasterRCNNVGG16 # NOQA
1212
from chainercv.links.model.fpn.faster_rcnn_fpn_resnet import FasterRCNNFPNResNet101 # NOQA
1313
from chainercv.links.model.fpn.faster_rcnn_fpn_resnet import FasterRCNNFPNResNet50 # NOQA
14+
from chainercv.links.model.fpn.faster_rcnn_fpn_resnet import KeypointRCNNFPNResNet101 # NOQA
15+
from chainercv.links.model.fpn.faster_rcnn_fpn_resnet import KeypointRCNNFPNResNet50 # NOQA
1416
from chainercv.links.model.fpn.faster_rcnn_fpn_resnet import MaskRCNNFPNResNet101 # NOQA
1517
from chainercv.links.model.fpn.faster_rcnn_fpn_resnet import MaskRCNNFPNResNet50 # NOQA
1618
from chainercv.links.model.resnet import ResNet101 # NOQA

chainercv/links/model/fpn/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from chainercv.links.model.fpn.faster_rcnn import FasterRCNN # NOQA
22
from chainercv.links.model.fpn.faster_rcnn_fpn_resnet import FasterRCNNFPNResNet101 # NOQA
33
from chainercv.links.model.fpn.faster_rcnn_fpn_resnet import FasterRCNNFPNResNet50 # NOQA
4+
from chainercv.links.model.fpn.faster_rcnn_fpn_resnet import KeypointRCNNFPNResNet101 # NOQA
5+
from chainercv.links.model.fpn.faster_rcnn_fpn_resnet import KeypointRCNNFPNResNet50 # NOQA
46
from chainercv.links.model.fpn.faster_rcnn_fpn_resnet import MaskRCNNFPNResNet101 # NOQA
57
from chainercv.links.model.fpn.faster_rcnn_fpn_resnet import MaskRCNNFPNResNet50 # NOQA
68
from chainercv.links.model.fpn.fpn import FPN # NOQA

chainercv/links/model/fpn/faster_rcnn.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ class FasterRCNN(chainer.Chain):
5050
"""
5151

5252
stride = 32
53-
_accepted_return_values = ('rois', 'bboxes', 'labels', 'scores', 'masks')
53+
_accepted_return_values = ('rois', 'bboxes', 'labels', 'scores',
54+
'masks', 'points', 'point_scores')
5455

5556
def __init__(self, extractor, rpn, bbox_head,
56-
mask_head, return_values,
57+
mask_head, keypoint_head, return_values,
5758
min_size=800, max_size=1333):
5859
for value_name in return_values:
5960
if value_name not in self._accepted_return_values:
@@ -64,8 +65,10 @@ def __init__(self, extractor, rpn, bbox_head,
6465

6566
self._store_rpn_outputs = 'rois' in self._return_values
6667
self._run_bbox = any([key in self._return_values
67-
for key in ['bboxes', 'labels', 'scores', 'masks']])
68+
for key in ['bboxes', 'labels', 'scores',
69+
'masks', 'points', 'point_scores']])
6870
self._run_mask = 'masks' in self._return_values
71+
self._run_keypoint = 'points' in self._return_values
6972
super(FasterRCNN, self).__init__()
7073

7174
with self.init_scope():
@@ -75,6 +78,8 @@ def __init__(self, extractor, rpn, bbox_head,
7578
self.bbox_head = bbox_head
7679
if self._run_mask:
7780
self.mask_head = mask_head
81+
if self._run_keypoint:
82+
self.keypoint_head = keypoint_head
7883

7984
self.min_size = min_size
8085
self.max_size = max_size
@@ -174,10 +179,9 @@ def predict(self, imgs):
174179
scores_cpu = [cuda.to_cpu(score) for score in scores]
175180
output.update({'bboxes': bboxes_cpu, 'labels': labels_cpu,
176181
'scores': scores_cpu})
177-
178-
if self._run_mask:
179182
rescaled_bboxes = [bbox * scale
180-
for scale, bbox in zip(scales, bboxes)]
183+
for scale, bbox in zip(scales, bboxes)]
184+
if self._run_mask:
181185
# Change bboxes to RoI and RoI indices format
182186
mask_rois_before_reordering, mask_roi_indices_before_reordering =\
183187
_list_to_flat(rescaled_bboxes)
@@ -200,6 +204,36 @@ def predict(self, imgs):
200204
# Currently MaskHead only supports numpy inputs
201205
masks_cpu = self.mask_head.decode(segms, bboxes_cpu, labels_cpu, sizes)
202206
output.update({'masks': masks_cpu})
207+
208+
if self._run_keypoint:
209+
(point_rois_before_reordering,
210+
point_roi_indices_before_reordering) = _list_to_flat(
211+
rescaled_bboxes)
212+
point_rois, point_roi_indices, order =\
213+
self.keypoint_head.distribute(
214+
point_rois_before_reordering,
215+
point_roi_indices_before_reordering)
216+
with chainer.using_config(
217+
'train', False), chainer.no_backprop_mode():
218+
point_maps = self.keypoint_head(
219+
hs, point_rois, point_roi_indices).data
220+
point_maps = point_maps[order]
221+
point_maps = _flat_to_list(
222+
point_maps, point_roi_indices_before_reordering, len(imgs))
223+
point_maps = [point_map if point_map is not None else
224+
self.xp.zeros(
225+
(0, self.keypoint_head.n_point,
226+
self.keypoint_head.point_map_size,
227+
self.keypoint_head.point_map_size),
228+
dtype=np.float32)
229+
for point_map in point_maps]
230+
point_maps = [
231+
chainer.backends.cuda.to_cpu(point_map)
232+
for point_map in point_maps]
233+
points_cpu, point_scores_cpu = self.keypoint_head.decode(
234+
point_maps, bboxes_cpu)
235+
output.update(
236+
{'points': points_cpu, 'point_scores': point_scores_cpu})
203237
return tuple([output[key] for key in self._return_values])
204238

205239
def prepare(self, imgs):

chainercv/links/model/fpn/faster_rcnn_fpn_resnet.py

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from chainercv.links.model.fpn.faster_rcnn import FasterRCNN
88
from chainercv.links.model.fpn.fpn import FPN
99
from chainercv.links.model.fpn.bbox_head import BboxHead
10+
from chainercv.links.model.fpn.keypoint_head import KeypointHead
1011
from chainercv.links.model.fpn.mask_head import MaskHead
1112
from chainercv.links.model.fpn.rpn import RPN
1213
from chainercv.links.model.resnet import ResNet101
@@ -45,6 +46,7 @@ class FasterRCNNFPNResNet(FasterRCNN):
4546
"""
4647

4748
def __init__(self, n_fg_class=None, pretrained_model=None,
49+
n_point=None,
4850
return_values=['bboxes', 'labels', 'scores'],
4951
min_size=800, max_size=1333):
5052
param, path = utils.prepare_pretrained_model(
@@ -63,6 +65,7 @@ def __init__(self, n_fg_class=None, pretrained_model=None,
6365
rpn=RPN(extractor.scales),
6466
bbox_head=BboxHead(param['n_fg_class'] + 1, extractor.scales),
6567
mask_head=MaskHead(param['n_fg_class'] + 1, extractor.scales),
68+
keypoint_head=KeypointHead(n_point, extractor.scales),
6669
return_values=return_values,
6770
min_size=min_size, max_size=max_size
6871
)
@@ -72,7 +75,7 @@ def __init__(self, n_fg_class=None, pretrained_model=None,
7275
self.extractor.base,
7376
self._base(pretrained_model='imagenet', arch='he'))
7477
elif path:
75-
chainer.serializers.load_npz(path, self)
78+
chainer.serializers.load_npz(path, self, strict=False)
7679

7780

7881
class MaskRCNNFPNResNet(FasterRCNNFPNResNet):
@@ -91,7 +94,30 @@ class MaskRCNNFPNResNet(FasterRCNNFPNResNet):
9194
def __init__(self, n_fg_class=None, pretrained_model=None,
9295
min_size=800, max_size=1333):
9396
super(MaskRCNNFPNResNet, self).__init__(
94-
n_fg_class, pretrained_model, ['masks', 'labels', 'scores'],
97+
n_fg_class, pretrained_model, None,
98+
['masks', 'labels', 'scores'],
99+
min_size, max_size)
100+
101+
102+
class KeypointRCNNFPNResNet(FasterRCNNFPNResNet):
103+
"""Feature Pyramid Networks with ResNet-50.
104+
105+
This is a model of Feature Pyramid Networks [#]_.
106+
This model uses :class:`~chainercv.links.ResNet50` as
107+
its base feature extractor.
108+
109+
.. [#] Tsung-Yi Lin et al.
110+
Feature Pyramid Networks for Object Detection. CVPR 2017
111+
112+
113+
"""
114+
115+
def __init__(self, n_fg_class=None, pretrained_model=None,
116+
n_point=None,
117+
min_size=800, max_size=1333):
118+
super(KeypointRCNNFPNResNet, self).__init__(
119+
n_fg_class, pretrained_model, n_point,
120+
['points', 'labels', 'scores', 'point_scores', 'bboxes'],
95121
min_size, max_size)
96122

97123

@@ -189,6 +215,52 @@ class MaskRCNNFPNResNet101(MaskRCNNFPNResNet):
189215
}
190216

191217

218+
class KeypointRCNNFPNResNet50(KeypointRCNNFPNResNet):
219+
"""Feature Pyramid Networks with ResNet-50.
220+
221+
This is a model of Feature Pyramid Networks [#]_.
222+
This model uses :class:`~chainercv.links.ResNet50` as
223+
its base feature extractor.
224+
225+
.. [#] Tsung-Yi Lin et al.
226+
Feature Pyramid Networks for Object Detection. CVPR 2017
227+
228+
229+
"""
230+
231+
_base = ResNet50
232+
_models = {
233+
'coco': {
234+
'param': {'n_fg_class': 80},
235+
'url': 'https://chainercv-models.preferred.jp/'
236+
'faster_rcnn_fpn_resnet50_mask_coco_trained_2019_03_15.npz',
237+
'cv2': True
238+
},
239+
}
240+
241+
242+
class KeypointRCNNFPNResNet101(KeypointRCNNFPNResNet):
243+
"""Feature Pyramid Networks with ResNet-50.
244+
245+
This is a model of Feature Pyramid Networks [#]_.
246+
This model uses :class:`~chainercv.links.ResNet50` as
247+
its base feature extractor.
248+
249+
.. [#] Tsung-Yi Lin et al.
250+
Feature Pyramid Networks for Object Detection. CVPR 2017
251+
252+
253+
"""
254+
255+
_base = ResNet50
256+
_models = {
257+
'coco': {
258+
'param': {'n_fg_class': 80},
259+
'url': '',
260+
'cv2': True
261+
},
262+
}
263+
192264

193265
def _copyparams(dst, src):
194266
if isinstance(dst, chainer.Chain):

chainercv/links/model/mask_rcnn/keypoint_head.py renamed to chainercv/links/model/fpn/keypoint_head.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
from chainercv.transforms.image.resize import resize
1616
from chainercv.utils.bbox.bbox_iou import bbox_iou
1717

18-
from chainercv.links.model.mask_rcnn.misc import point_to_roi_points
19-
from chainercv.links.model.mask_rcnn.misc import within_bbox
18+
from chainercv.links.model.fpn.keypoint_utils import point_to_roi_points
19+
from chainercv.links.model.fpn.keypoint_utils import within_bbox
2020

2121

2222
# make a bilinear interpolation kernel
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from __future__ import division
2+
3+
import numpy as np
4+
5+
import chainer
6+
7+
8+
def point_to_roi_points(
9+
point, visible, bbox, point_map_size):
10+
xp = chainer.backends.cuda.get_array_module(point)
11+
12+
R, K, _ = point.shape
13+
14+
roi_point = xp.zeros((len(bbox), K, 2))
15+
roi_visible = xp.zeros((len(bbox), K), dtype=np.bool)
16+
17+
offset_y = bbox[:, 0]
18+
offset_x = bbox[:, 1]
19+
scale_y = point_map_size / (bbox[:, 2] - bbox[:, 0])
20+
scale_x = point_map_size / (bbox[:, 3] - bbox[:, 1])
21+
22+
for k in range(K):
23+
y_boundary_index = xp.where(point[:, k, 0] == bbox[:, 2])[0]
24+
x_boundary_index = xp.where(point[:, k, 1] == bbox[:, 3])[0]
25+
26+
ys = (point[:, k, 0] - offset_y) * scale_y
27+
ys = xp.floor(ys)
28+
if len(y_boundary_index) > 0:
29+
ys[y_boundary_index] = point_map_size - 1
30+
xs = (point[:, k, 1] - offset_x) * scale_x
31+
xs = xp.floor(xs)
32+
if len(x_boundary_index) > 0:
33+
xs[x_boundary_index] = point_map_size - 1
34+
35+
valid = xp.logical_and(
36+
xp.logical_and(
37+
xp.logical_and(ys >= 0, xs >= 0),
38+
xp.logical_and(ys < point_map_size, xs < point_map_size)),
39+
visible[:, k])
40+
41+
roi_point[:, k, 0] = ys
42+
roi_point[:, k, 1] = xs
43+
roi_visible[:, k] = valid
44+
return roi_point, roi_visible
45+
46+
47+
def within_bbox(point, bbox):
48+
y_within = (point[:, :, 0] >= bbox[:, 0][:, None]) & (
49+
point[:, :, 0] <= bbox[:, 2][:, None])
50+
x_within = (point[:, :, 1] >= bbox[:, 1][:, None]) & (
51+
point[:, :, 1] <= bbox[:, 3][:, None])
52+
return y_within & x_within

chainercv/links/model/fpn/mask_utils.py

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -155,50 +155,3 @@ def _expand_boxes(bbox, scale):
155155
expanded_bbox[:, 3] = x_c + w_half
156156

157157
return expanded_bbox
158-
159-
160-
def point_to_roi_points(
161-
point, visible, bbox, point_map_size):
162-
xp = chainer.backends.cuda.get_array_module(point)
163-
164-
R, K, _ = point.shape
165-
166-
roi_point = xp.zeros((len(bbox), K, 2))
167-
roi_visible = xp.zeros((len(bbox), K), dtype=np.bool)
168-
169-
offset_y = bbox[:, 0]
170-
offset_x = bbox[:, 1]
171-
scale_y = point_map_size / (bbox[:, 2] - bbox[:, 0])
172-
scale_x = point_map_size / (bbox[:, 3] - bbox[:, 1])
173-
174-
for k in range(K):
175-
y_boundary_index = xp.where(point[:, k, 0] == bbox[:, 2])[0]
176-
x_boundary_index = xp.where(point[:, k, 1] == bbox[:, 3])[0]
177-
178-
ys = (point[:, k, 0] - offset_y) * scale_y
179-
ys = xp.floor(ys)
180-
if len(y_boundary_index) > 0:
181-
ys[y_boundary_index] = point_map_size - 1
182-
xs = (point[:, k, 1] - offset_x) * scale_x
183-
xs = xp.floor(xs)
184-
if len(x_boundary_index) > 0:
185-
xs[x_boundary_index] = point_map_size - 1
186-
187-
valid = xp.logical_and(
188-
xp.logical_and(
189-
xp.logical_and(ys >= 0, xs >= 0),
190-
xp.logical_and(ys < point_map_size, xs < point_map_size)),
191-
visible[:, k])
192-
193-
roi_point[:, k, 0] = ys
194-
roi_point[:, k, 1] = xs
195-
roi_visible[:, k] = valid
196-
return roi_point, roi_visible
197-
198-
199-
def within_bbox(point, bbox):
200-
y_within = (point[:, :, 0] >= bbox[:, 0][:, None]) & (
201-
point[:, :, 0] <= bbox[:, 2][:, None])
202-
x_within = (point[:, :, 1] >= bbox[:, 1][:, None]) & (
203-
point[:, :, 1] <= bbox[:, 3][:, None])
204-
return y_within & x_within

chainercv/links/model/mask_rcnn/__init__.py

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)