def _suppress(raw_bbox, raw_score, nms_thresh, score_thresh): xp = cuda.get_array_module(raw_bbox, raw_score) bbox = [] label = [] score = [] for l in range(raw_score.shape[1] - 1): bbox_l = raw_bbox[:, l + 1] score_l = raw_score[:, l + 1] mask = score_l >= score_thresh bbox_l = bbox_l[mask] score_l = score_l[mask] order = argsort(-score_l) bbox_l = bbox_l[order] score_l = score_l[order] indices = utils.non_maximum_suppression(bbox_l, nms_thresh) bbox_l = bbox_l[indices] score_l = score_l[indices] bbox.append(bbox_l) label.append(xp.array((l, ) * len(bbox_l))) score.append(score_l) bbox = xp.vstack(bbox).astype(np.float32) label = xp.hstack(label).astype(np.int32) score = xp.hstack(score).astype(np.float32) return bbox, label, score
def decode(self, locs, confs, anchors, in_shape): """Decodes back to coordinates of RoIs. This method decodes :obj:`locs` and :obj:`confs` returned by a FPN network back to :obj:`rois` and :obj:`roi_indices`. Args: locs (list of arrays): A list of arrays whose shape is :math:`(N, K_l, 4)`, where :math:`N` is the size of batch and :math:`K_l` is the number of the anchor boxes of the :math:`l`-th level. confs (list of arrays): A list of array whose shape is :math:`(N, K_l)`. anchors (list of arrays): Anchor boxes returned by :meth:`anchors`. in_shape (tuple of ints): The shape of input of array the feature extractor. Returns: tuple of two arrays: :obj:`rois` and :obj:`roi_indices`. * **rois**: An array of shape :math:`(R, 4)`, \ where :math:`R` is the total number of RoIs in the given batch. * **roi_indices** : An array of shape :math:`(R,)`. """ if chainer.config.train: nms_limit_pre = self._train_nms_limit_pre nms_limit_post = self._train_nms_limit_post else: nms_limit_pre = self._test_nms_limit_pre nms_limit_post = self._test_nms_limit_post rois = [] roi_indices = [] for i in range(in_shape[0]): roi = [] conf = [] for l in range(len(self._scales)): loc_l = locs[l].array[i] conf_l = confs[l].array[i] roi_l = anchors[l].copy() # tlbr -> yxhw roi_l[:, 2:] -= roi_l[:, :2] roi_l[:, :2] += roi_l[:, 2:] / 2 # offset roi_l[:, :2] += loc_l[:, :2] * roi_l[:, 2:] roi_l[:, 2:] *= self.xp.exp( self.xp.minimum(loc_l[:, 2:], exp_clip)) # yxhw -> tlbr roi_l[:, :2] -= roi_l[:, 2:] / 2 roi_l[:, 2:] += roi_l[:, :2] # clip roi_l[:, :2] = self.xp.maximum(roi_l[:, :2], 0) roi_l[:, 2:] = self.xp.minimum(roi_l[:, 2:], self.xp.array(in_shape[2:])) order = argsort(-conf_l)[:nms_limit_pre] roi_l = roi_l[order] conf_l = conf_l[order] mask = (roi_l[:, 2:] - roi_l[:, :2] > 0).all(axis=1) roi_l = roi_l[mask] conf_l = conf_l[mask] indices = utils.non_maximum_suppression(roi_l, self._nms_thresh, limit=nms_limit_post) roi_l = roi_l[indices] conf_l = conf_l[indices] roi.append(roi_l) conf.append(conf_l) roi = self.xp.vstack(roi).astype(np.float32) conf = self.xp.hstack(conf).astype(np.float32) order = argsort(-conf)[:nms_limit_post] roi = roi[order] rois.append(roi) roi_indices.append(self.xp.array((i, ) * len(roi))) rois = self.xp.vstack(rois).astype(np.float32) roi_indices = self.xp.hstack(roi_indices).astype(np.int32) return rois, roi_indices