def find_top_rpn_proposals(self, rpn_cls_score_list, rpn_bbox_offset_list, anchors_list, im_info): prev_nms_top_n = (self.cfg.train_prev_nms_top_n if self.training else self.cfg.test_prev_nms_top_n) post_nms_top_n = (self.cfg.train_post_nms_top_n if self.training else self.cfg.test_post_nms_top_n) return_rois = [] for bid in range(im_info.shape[0]): batch_proposal_list = [] batch_score_list = [] batch_level_list = [] for l, (rpn_cls_score, rpn_bbox_offset, anchors) in enumerate( zip(rpn_cls_score_list, rpn_bbox_offset_list, anchors_list)): # get proposals and scores offsets = rpn_bbox_offset[bid].transpose(2, 3, 0, 1).reshape(-1, 4) proposals = self.box_coder.decode(anchors, offsets) scores = rpn_cls_score[bid].transpose(1, 2, 0).flatten() scores.detach() # prev nms top n scores, order = F.topk(scores, descending=True, k=prev_nms_top_n) proposals = proposals[order, :] batch_proposal_list.append(proposals) batch_score_list.append(scores) batch_level_list.append(F.full_like(scores, l)) # gather proposals, scores, level proposals = F.concat(batch_proposal_list, axis=0) scores = F.concat(batch_score_list, axis=0) levels = F.concat(batch_level_list, axis=0) proposals = layers.get_clipped_boxes(proposals, im_info[bid]) # filter invalid proposals and apply total level nms keep_mask = layers.filter_boxes(proposals) _, keep_inds = F.cond_take(keep_mask == 1, keep_mask) proposals = proposals[keep_inds, :] scores = scores[keep_inds] levels = levels[keep_inds] nms_keep_inds = layers.batched_nms(proposals, scores, levels, self.cfg.rpn_nms_threshold, post_nms_top_n) # generate rois to rcnn head, rois shape (N, 5), info [batch_id, x1, y1, x2, y2] rois = F.concat([proposals, scores.reshape(-1, 1)], axis=1) rois = rois[nms_keep_inds] batch_inds = F.full((rois.shape[0], 1), bid) batch_rois = F.concat([batch_inds, rois[:, :4]], axis=1) return_rois.append(batch_rois) return_rois = F.concat(return_rois, axis=0) return return_rois.detach()
def __call__(self, matrix): """ matrix(tensor): A two dim tensor with shape of (N, M). N is number of GT-boxes, while M is the number of anchors in detection. """ assert len(matrix.shape) == 2 max_scores = matrix.max(axis=0) match_indices = F.argmax(matrix, axis=0) # default ignore label: -1 labels = F.full_like(match_indices, -1) for label, low, high in zip(self.labels, self.thresholds[:-1], self.thresholds[1:]): mask = (max_scores >= low) & (max_scores < high) labels[mask] = label if self.allow_low_quality_matches: mask = (matrix == F.max(matrix, axis=1, keepdims=True)).sum(axis=0) > 0 labels[mask] = 1 return match_indices, labels