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

update fcis variables names #587

Merged
merged 1 commit into from
Apr 27, 2018
Merged
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
36 changes: 18 additions & 18 deletions chainercv/experimental/links/model/fcis/fcis.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def __call__(self, x, scale=1.):
Variable, Variable, Variable, array, array:
Returns tuple of five values listed below.

* **roi_mask_scores**: Class-agnostic segmentation scores for \
* **roi_cmask_scores**: Class-agnostic clipped mask scores for \
the proposed ROIs. Its shape is :math:`(R', 2, RH, RW)`
* **ag_locs**: Class-agnostic offsets and scalings for \
the proposed RoIs. Its shape is :math:`(R', 2, 4)`.
Expand All @@ -137,9 +137,9 @@ def __call__(self, x, scale=1.):
rpn_features, roi_features = self.extractor(x)
rpn_locs, rpn_scores, rois, roi_indices, anchor = self.rpn(
rpn_features, img_size, scale)
roi_mask_scores, ag_locs, cls_scores, rois, roi_indices = \
roi_cmask_scores, roi_ag_locs, roi_cls_scores, rois, roi_indices = \
self.head(roi_features, rois, roi_indices, img_size)
return roi_mask_scores, ag_locs, cls_scores, rois, roi_indices
return roi_cmask_scores, roi_ag_locs, roi_cls_scores, rois, roi_indices

def prepare(self, img):
"""Preprocess an image for feature extraction.
Expand Down Expand Up @@ -257,27 +257,27 @@ def predict(self, imgs):
# inference
img_var = chainer.Variable(self.xp.array(img[None]))
scale = img_var.shape[3] / size[1]
roi_mask_scores, _, cls_scores, bboxes, _ = \
roi_cmask_scores, _, roi_cls_scores, bboxes, _ = \
self.__call__(img_var, scale)

# We are assuming that batch size is 1.
roi_mask_score = roi_mask_scores.array
cls_score = cls_scores.array
roi_cmask_score = roi_cmask_scores.array
roi_cls_score = roi_cls_scores.array
bbox = bboxes / scale

# shape: (n_rois, 4)
bbox[:, 0::2] = self.xp.clip(bbox[:, 0::2], 0, size[0])
bbox[:, 1::2] = self.xp.clip(bbox[:, 1::2], 0, size[1])

roi_mask_prob = F.softmax(roi_mask_score).array[:, 1, :, :]
cls_prob = F.softmax(cls_score).array
roi_cmask_prob = F.softmax(roi_cmask_score).array[:, 1, :, :]
roi_cls_prob = F.softmax(roi_cls_score).array

roi_mask_prob = chainer.cuda.to_cpu(roi_mask_prob)
cls_prob = chainer.cuda.to_cpu(cls_prob)
roi_cmask_prob = chainer.cuda.to_cpu(roi_cmask_prob)
roi_cls_prob = chainer.cuda.to_cpu(roi_cls_prob)
bbox = chainer.cuda.to_cpu(bbox)

roi_mask_prob, bbox, label, cls_prob = mask_voting(
roi_mask_prob, bbox, cls_prob, size,
roi_cmask_prob, bbox, label, roi_cls_prob = mask_voting(
roi_cmask_prob, bbox, roi_cls_prob, size,
self.score_thresh, self.nms_thresh,
self.mask_merge_thresh, self.binary_thresh,
limit=self.limit, bg_label=0)
Expand All @@ -287,24 +287,24 @@ def predict(self, imgs):
keep_indices = np.where(
(height > self.min_drop_size) &
(width > self.min_drop_size))[0]
roi_mask_prob = roi_mask_prob[keep_indices]
roi_cmask_prob = roi_cmask_prob[keep_indices]
bbox = bbox[keep_indices]
label = label[keep_indices]
cls_prob = cls_prob[keep_indices]
roi_cls_prob = roi_cls_prob[keep_indices]

mask = np.zeros(
(len(roi_mask_prob), size[0], size[1]), dtype=np.bool)
for i, (roi_msk_pb, bb) in enumerate(zip(roi_mask_prob, bbox)):
(len(roi_cmask_prob), size[0], size[1]), dtype=np.bool)
for i, (roi_cmsk_pb, bb) in enumerate(zip(roi_cmask_prob, bbox)):
bb = np.round(bb).astype(np.int32)
y_min, x_min, y_max, x_max = bb
roi_msk_pb = resize(
roi_msk_pb.astype(np.float32)[None],
roi_cmsk_pb.astype(np.float32)[None],
(y_max - y_min, x_max - x_min))
roi_msk = (roi_msk_pb > self.binary_thresh)[0]
mask[i, y_min:y_max, x_min:x_max] = roi_msk

masks.append(mask)
labels.append(label)
scores.append(cls_prob)
scores.append(roi_cls_prob)

return masks, labels, scores
40 changes: 20 additions & 20 deletions chainercv/experimental/links/model/fcis/fcis_resnet101.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,35 +277,35 @@ def __call__(self, x, rois, roi_indices, img_size):
h_ag_loc = self.ag_loc(h)

# PSROI pooling and regression
roi_mask_scores, ag_locs, cls_scores = self._pool(
roi_cmask_scores, roi_ag_locs, roi_cls_scores = self._pool(
h_cls_seg, h_ag_loc, rois, roi_indices)
if self.iter2:
# 2nd Iteration
# get rois2 for more precise prediction
ag_locs = ag_locs.array
roi_ag_locs = roi_ag_locs.array
mean = self.xp.array(self.loc_normalize_mean)
std = self.xp.array(self.loc_normalize_std)
locs = ag_locs[:, 1, :]
locs = (locs * std + mean).astype(np.float32)
rois2 = loc2bbox(rois, locs)
roi_locs = roi_ag_locs[:, 1, :]
roi_locs = (roi_locs * std + mean).astype(np.float32)
rois2 = loc2bbox(rois, roi_locs)

rois2[:, 0::2] = self.xp.clip(rois2[:, 0::2], 0, img_size[0])
rois2[:, 1::2] = self.xp.clip(rois2[:, 1::2], 0, img_size[1])

# PSROI pooling and regression
roi_mask_scores2, ag_locs2, cls_scores2 = self._pool(
roi_cmask_scores2, roi_ag_locs2, roi_cls_scores2 = self._pool(
h_cls_seg, h_ag_loc, rois2, roi_indices)

# concat 1st and 2nd iteration results
rois = self.xp.concatenate((rois, rois2))
roi_indices = self.xp.concatenate((roi_indices, roi_indices))
roi_mask_scores = F.concat(
(roi_mask_scores, roi_mask_scores2), axis=0)
ag_locs = F.concat(
(ag_locs, ag_locs2), axis=0)
cls_scores = F.concat(
(cls_scores, cls_scores2), axis=0)
return roi_mask_scores, ag_locs, cls_scores, rois, roi_indices
roi_cmask_scores = F.concat(
(roi_cmask_scores, roi_cmask_scores2), axis=0)
roi_ag_locs = F.concat(
(roi_ag_locs, roi_ag_locs2), axis=0)
roi_cls_scores = F.concat(
(roi_cls_scores, roi_cls_scores2), axis=0)
return roi_cmask_scores, roi_ag_locs, roi_cls_scores, rois, roi_indices

def _pool(
self, h_cls_seg, h_ag_loc, rois, roi_indices):
Expand All @@ -319,28 +319,28 @@ def _pool(
(-1, self.n_class, 2, self.roi_size, self.roi_size))

# shape: (n_roi, 2*4, roi_size, roi_size)
ag_loc_scores = psroi_pooling_2d(
roi_ag_loc_scores = psroi_pooling_2d(
h_ag_loc, rois, roi_indices,
2 * 4, self.roi_size, self.roi_size,
self.spatial_scale, self.group_size)

# shape: (n_roi, n_class)
cls_scores = _global_average_pooling_2d(
roi_cls_scores = _global_average_pooling_2d(
F.max(roi_seg_scores, axis=2))

# Bbox Regression
# shape: (n_roi, 2*4)
ag_locs = _global_average_pooling_2d(ag_loc_scores)
ag_locs = ag_locs.reshape((-1, 2, 4))
roi_ag_locs = _global_average_pooling_2d(roi_ag_loc_scores)
roi_ag_locs = roi_ag_locs.reshape((-1, 2, 4))

# Mask Regression
# shape: (n_roi, n_class, 2, roi_size, roi_size)
max_cls_indices = cls_scores.array.argmax(axis=1)
max_cls_indices = roi_cls_scores.array.argmax(axis=1)
# shape: (n_roi, 2, roi_size, roi_size)
roi_mask_scores = roi_seg_scores[
roi_cmask_scores = roi_seg_scores[
self.xp.arange(len(max_cls_indices)), max_cls_indices]

return roi_mask_scores, ag_locs, cls_scores
return roi_cmask_scores, roi_ag_locs, roi_cls_scores


def _global_average_pooling_2d(x):
Expand Down
79 changes: 40 additions & 39 deletions chainercv/experimental/links/model/fcis/utils/mask_voting.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,24 @@


def _mask_aggregation(
bbox, mask_prob, mask_weight,
bbox, cmask_prob, cmask_weight,
size, binary_thresh
):
assert bbox.shape[0] == len(mask_prob)
assert bbox.shape[0] == mask_weight.shape[0]
assert bbox.shape[0] == len(cmask_prob)
assert bbox.shape[0] == cmask_weight.shape[0]

mask = np.zeros(size, dtype=np.float32)
for bb, msk_pb, msk_w in zip(bbox, mask_prob, mask_weight):
aggregated_msk = np.zeros(size, dtype=np.float32)
for bb, cmsk_pb, cmsk_w in zip(bbox, cmask_prob, cmask_weight):
bb = np.round(bb).astype(np.int32)
y_min, x_min, y_max, x_max = bb
if y_max - y_min > 0 and x_max - x_min > 0:
msk_pb = resize(
msk_pb.astype(np.float32)[None],
cmsk_pb = resize(
cmsk_pb.astype(np.float32)[None],
(y_max - y_min, x_max - x_min))
msk_m = (msk_pb >= binary_thresh).astype(np.float32)[0]
mask[y_min:y_max, x_min:x_max] += msk_m * msk_w
cmsk_m = (cmsk_pb >= binary_thresh).astype(np.float32)[0]
aggregated_msk[y_min:y_max, x_min:x_max] += cmsk_m * cmsk_w

y_indices, x_indices = np.where(mask >= binary_thresh)
y_indices, x_indices = np.where(aggregated_msk >= binary_thresh)
if len(y_indices) == 0 or len(x_indices) == 0:
return None, None
else:
Expand All @@ -32,15 +32,15 @@ def _mask_aggregation(
x_max = x_indices.max() + 1
x_min = x_indices.min()

c_bbox = np.array(
aggregated_bb = np.array(
[y_min, x_min, y_max, x_max],
dtype=np.float32)
c_mask = mask[y_min:y_max, x_min:x_max]
return c_mask[None], c_bbox[None]
aggregated_cmsk = aggregated_msk[y_min:y_max, x_min:x_max]
return aggregated_cmsk[None], aggregated_bb[None]


def mask_voting(
roi_mask_prob, bbox, cls_prob, size,
roi_cmask_prob, bbox, roi_cls_prob, size,
score_thresh, nms_thresh,
mask_merge_thresh, binary_thresh,
limit=100, bg_label=0
Expand All @@ -60,7 +60,7 @@ def mask_voting(
* :math:`RW` is the height of pooled image.

Args:
roi_mask_prob (array): A mask probability array whose shape is
roi_cmask_prob (array): A mask probability array whose shape is
:math:`(R, RH, RW)`.
bbox (array): A bounding box array whose shape is
:math:`(R, 4)`.
Expand All @@ -78,7 +78,8 @@ def mask_voting(

Returns:
array, array, array, array:
* **v_mask_score**: Merged masks. Its shapes is :math:`(N, RH, RW)`.
* **v_cmask_prob**: Merged mask probability. Its shapes is \
:math:`(N, RH, RW)`.
* **v_bbox**: Bounding boxes for the merged masks. Its shape is \
:math:`(N, 4)`.
* **v_label**: Class labels for the merged masks. Its shape is \
Expand All @@ -88,10 +89,10 @@ def mask_voting(

"""

roi_mask_size = roi_mask_prob.shape[1:]
n_class = cls_prob.shape[1]
roi_cmask_size = roi_cmask_prob.shape[1:]
n_class = roi_cls_prob.shape[1]

v_mask_prob = []
v_cmask_prob = []
v_bbox = []
v_label = []
v_cls_prob = []
Expand All @@ -104,7 +105,7 @@ def mask_voting(
if label == bg_label:
continue
# non maximum suppression
score_l = cls_prob[:, label]
score_l = roi_cls_prob[:, label]
keep_indices = non_maximum_suppression(
bbox, nms_thresh, score_l)
bbox_l = bbox[keep_indices]
Expand All @@ -126,47 +127,47 @@ def mask_voting(
bbox_l = bbox_l[keep_indices]
score_l = score_l[keep_indices]

v_mask_prob_l = []
v_cmask_prob_l = []
v_bbox_l = []
v_score_l = []

for i, bb in enumerate(bbox_l):
iou = bbox_iou(bbox, bb[np.newaxis, :])
keep_indices = np.where(iou >= mask_merge_thresh)[0]
mask_weight = cls_prob[keep_indices, label]
mask_weight = mask_weight / mask_weight.sum()
mask_prob_i = roi_mask_prob[keep_indices]
cmask_weight = roi_cls_prob[keep_indices, label]
cmask_weight = cmask_weight / cmask_weight.sum()
cmask_prob_i = roi_cmask_prob[keep_indices]
bbox_i = bbox[keep_indices]
c_mask, c_bbox = _mask_aggregation(
bbox_i, mask_prob_i, mask_weight, size, binary_thresh)
if c_mask is not None and c_bbox is not None:
c_mask = resize(
c_mask.astype(np.float32),
roi_mask_size)
v_mask_prob_l.append(c_mask)
v_bbox_l.append(c_bbox)
m_cmask, m_bbox = _mask_aggregation(
bbox_i, cmask_prob_i, cmask_weight, size, binary_thresh)
if m_cmask is not None and m_bbox is not None:
m_cmask = resize(
m_cmask.astype(np.float32),
roi_cmask_size)
v_cmask_prob_l.append(m_cmask)
v_bbox_l.append(m_bbox)
v_score_l.append(score_l[i])

if len(v_mask_prob_l) > 0:
v_mask_prob_l = np.concatenate(v_mask_prob_l)
if len(v_cmask_prob_l) > 0:
v_cmask_prob_l = np.concatenate(v_cmask_prob_l)
v_bbox_l = np.concatenate(v_bbox_l)
v_score_l = np.array(v_score_l)

v_label_l = np.repeat(label - 1, v_bbox_l.shape[0])
v_label_l = v_label_l.astype(np.int32)
v_mask_prob.append(v_mask_prob_l)
v_cmask_prob.append(v_cmask_prob_l)
v_bbox.append(v_bbox_l)
v_label.append(v_label_l)
v_cls_prob.append(v_score_l)

if len(v_mask_prob) > 0:
v_mask_prob = np.concatenate(v_mask_prob)
if len(v_cmask_prob) > 0:
v_cmask_prob = np.concatenate(v_cmask_prob)
v_bbox = np.concatenate(v_bbox)
v_label = np.concatenate(v_label)
v_cls_prob = np.concatenate(v_cls_prob)
else:
v_mask_prob = np.empty((0, roi_mask_size[0], roi_mask_size[1]))
v_cmask_prob = np.empty((0, roi_cmask_size[0], roi_cmask_size[1]))
v_bbox = np.empty((0, 4))
v_label = np.empty((0, ))
v_cls_prob = np.empty((0, ))
return v_mask_prob, v_bbox, v_label, v_cls_prob
return v_cmask_prob, v_bbox, v_label, v_cls_prob