def match_anchor_to_bbox(ground_truth, anchors, device, iou_threshold=0.5): """Assign ground-truth bounding boxes to anchor boxes similar to them.""" num_anchors, num_gt_boxes = anchors.shape[0], ground_truth.shape[0] # Element `x_ij` in the `i^th` row and `j^th` column is the IoU # of the anchor box `anc_i` to the ground-truth bounding box `box_j` jaccard = box_iou(anchors, ground_truth) # Initialize the tensor to hold assigned ground truth bbox for each anchor anchors_bbox_map = np.full((num_anchors, ), fill_value=-1, dtype=np.int32, ctx=device) # Assign ground truth bounding box according to the threshold max_ious, indices = np.max(jaccard, axis=1), np.argmax(jaccard, axis=1) anc_i = np.nonzero(max_ious >= iou_threshold)[0] box_j = indices[max_ious >= iou_threshold] anchors_bbox_map[anc_i] = box_j # Find the largest iou for each bbox col_discard = np.full((num_anchors, ), -1) row_discard = np.full((num_gt_boxes, ), -1) for _ in range(num_gt_boxes): max_idx = np.argmax(jaccard) box_idx = (max_idx % num_gt_boxes).astype('int32') anc_idx = (max_idx / num_gt_boxes).astype('int32') anchors_bbox_map[anc_idx] = box_idx jaccard[:, box_idx] = col_discard jaccard[anc_idx, :] = row_discard return anchors_bbox_map
def multibox_target(anchors, labels): batch_size, anchors = labels.shape[0], anchors.squeeze(0) batch_offset, batch_mask, batch_class_labels = [], [], [] device, num_anchors = anchors.ctx, anchors.shape[0] print(labels.shape) print(batch_size) for i in range(batch_size): label = labels[i, :, :] anchors_bbox_map = match_anchor_to_bbox(label[:, 1:], anchors, device) # [-1, 0, 1, -1 , 1] bbox_mask = np.tile((np.expand_dims((anchors_bbox_map >= 0), axis=-1)), (1, 4)).astype('int32') # Initialize class_labels and assigned bbox coordinates with zeros class_labels = np.zeros(num_anchors, dtype=np.int32, ctx=device) assigned_bb = np.zeros((num_anchors, 4), dtype=np.float32, ctx=device) # Assign class labels to the anchor boxes using matched gt bbox labels # If no gt bbox is assigned to an anchor box, then let the # class_labels and assigned_bb remain zero, i.e the background class indices_true = np.nonzero(anchors_bbox_map >= 0)[0] #[1,2,4] print(indices_true) bb_idx = anchors_bbox_map[indices_true] #[0, 1, 1] class_labels[indices_true] = label[bb_idx, 0].astype( 'int32') + 1 # Get category assigned_bb[indices_true] = label[bb_idx, 1:] # Get ground-truth # offset transformations offset = offset_boxes(anchors, assigned_bb) * bbox_mask batch_offset.append(offset.reshape(-1)) batch_mask.append(bbox_mask.reshape(-1)) batch_class_labels.append(class_labels) bbox_offset = np.stack(batch_offset) bbox_mask = np.stack(batch_mask) class_labels = np.stack(batch_class_labels) return (bbox_offset, bbox_mask, class_labels)
def nms(boxes, scores, iou_threshold): # sorting scores by the descending order and return their indices B = scores.argsort()[::-1] keep = [] # boxes indices that will be kept while B.size > 0: i = B[0] # Get max confidence keep.append(i) if B.size == 1: break iou = box_iou(boxes[i, :].reshape(-1, 4), boxes[B[1:], :].reshape(-1, 4)).reshape(-1) inds = np.nonzero(iou <= iou_threshold)[0] B = B[inds + 1] return np.array(keep, dtype=np.int32, ctx=boxes.ctx)
def dnp_func(a, b=None, split_inputs=(), ret_type=list): """ Dummy Doc: dnp_func is using the same np.xxx operators """ ret_lst = [] # unsupported indexing case ret_lst.append(a[:, a[1, :] > 0]) # unsupported operator ret_lst.append(np.nonzero(b)) # unsupported operator case ret_lst.append(tuple(np.split(split_inputs[0], split_inputs[1]))) return ret_type(ret_lst)