Ejemplo n.º 1
0
def test_IoU():
    b_1 = [[0, 2, 1, 3], [0, 2, 1, 3], [0, 5, 7, 10], [0, 0, 0, 0]]
    b_2 = [[0, 2 + 5.5, 1 + 5.5, 3 + 5.5], [0, 2 + 0.5, 1 + 0.5, 3 + 0.5]]
    # b_2 = [i + 0.5 for i in b_2]
    # print(bbox_IOU(b_1, b_2, align=True))

    re = bboxtool.bbox_list_IOU(b_1, b_2, align=False)
    print(re)
    re = bboxtool.bbox_list_IOU(b_1, b_2, align=True)
    print(re)
Ejemplo n.º 2
0
    def clustering(self, num_cluster, max_iter=100):
        n_bbox = len(self._bbox_list)
        # init centroid
        centroid = self._bbox_list[np.random.choice(n_bbox,
                                                    num_cluster,
                                                    replace=False)]

        prev_label = np.zeros(n_bbox)
        cnt = 0
        while True:
            cnt += 1
            iou = bboxtool.bbox_list_IOU(self._bbox_list, centroid, align=True)
            dist = 1 - iou
            label = np.argmin(dist, axis=-1)
            for k in range(num_cluster):
                mean_h = np.median(self._bbox_list[label == k, 3] -
                                   self._bbox_list[label == k, 1],
                                   axis=0)
                mean_w = np.median(self._bbox_list[label == k, 2] -
                                   self._bbox_list[label == k, 0],
                                   axis=0)
                centroid[k] = [0, 0, mean_w, mean_h]

            if (prev_label == label).all() or cnt > max_iter:
                break
            prev_label = label

        self._centroid = centroid
        self._label = label

        return centroid
Ejemplo n.º 3
0
    def mean_iou(self, num_cluster=None):
        if num_cluster is not None:
            self.clustering(num_cluster=num_cluster, max_iter=100)
        try:
            self._centroid
        except AttributeError:
            self.clustering(num_cluster=5, max_iter=100)

        iou = bboxtool.bbox_list_IOU(self._bbox_list,
                                     self._centroid,
                                     align=True)
        max_iou = np.amax(iou, axis=-1)
        return np.mean(max_iou)
Ejemplo n.º 4
0
    def _get_gt_mask(self, gt_bboxes, class_labels, rescale_shape):

        init_anchors = self.init_anchors_dict[rescale_shape[0]]
        ind_list = init_anchors['index']
        sub2ind = init_anchors['sub2ind']

        gt_mask = copy.deepcopy(self.init_gt_mask_dict[rescale_shape[0]])
        one_hot_label = vec2onehot(class_labels, self._n_class)
        gt_cxy = np.stack([(gt_bboxes[:, 0] + gt_bboxes[:, 2]) // 2,
                           (gt_bboxes[:, 1] + gt_bboxes[:, 3]) // 2],
                          axis=-1)

        iou_mat = bboxtool.bbox_list_IOU(gt_bboxes,
                                         bboxtool.cxywh2xyxy(
                                             self._anchor_boxes),
                                         align=True)
        target_anchor_list = np.argmax(iou_mat, axis=-1)
        # print()
        # out_anchor_list = []
        for gt_id, (target_anchor_idx,
                    gt_bbox) in enumerate(zip(target_anchor_list, gt_bboxes)):
            if iou_mat[gt_id, target_anchor_idx] == 0:
                continue
            anchor_idx_list = []
            for scale_id, stride in enumerate(self._stride_list):
                anchor_feat_cxy = gt_cxy[gt_id] // stride
                gt_feat_cxy = gt_cxy[gt_id] / stride

                # print(gt_bboxes[gt_id],gt_cxy[gt_id])
                anchor_idx_list += sub2ind[(scale_id, anchor_feat_cxy[1],
                                            anchor_feat_cxy[0])]

            anchor_idx = anchor_idx_list[target_anchor_idx]
            scale_id, prior_id, row_id, col_id, anchor_xyxy, anchor_stride =\
                self._get_anchor_property(anchor_idx, ind_list)

            gt_mask[scale_id][prior_id][row_id, col_id, :4] =\
                bboxtool.xyxy2yolotcoord([gt_bbox], anchor_xyxy, anchor_stride, [col_id, row_id])
            gt_mask[scale_id][prior_id][row_id, col_id, 4] = 1
            # TODO
            # multi-class
            gt_mask[scale_id][prior_id][row_id, col_id,
                                        5:] = one_hot_label[gt_id]
            # out_anchor_list.append(anchor_list[anchor_idx])
            # out_anchor_list.append([col_id*anchor_stride, row_id*anchor_stride] + anchor_xyxy)

        return gt_mask  #, out_anchor_list
Ejemplo n.º 5
0
def mAP(pred_bboxes, pred_classes, pred_conf, gt_bboxes, gt_classes, IoU_thr,
        pred_im_size, gt_im_size):
    """ evaluate object detection performance using mAP

        Args:
            pred_bboxes, gt_bboxes (list): prediction and groundtruth bounding box
                with size [n_bbox, 4] with format xyxy
            pred_classes, gt_classes (list): prediction and groundtruth class labels
                corresponding the the pred_bboxes and gt_bboxes
            pred_conf (list): confidence score of each prediction
            IoU_thr (float): IoU threshold to determine the correct detection
            pred_im_size, gt_im_size (int or list of two int): image size for prediction
                groundtruth bounding box

        Returns:
            a scalar value of mAP (float) 
    """
    # bbox xyxy

    pred_classes, gt_classes, pred_bboxes, gt_bboxes, pred_conf =\
        utils.to_nparray([pred_classes, gt_classes, pred_bboxes, gt_bboxes, pred_conf])
    # rescale bbox to the same scale
    pred_bboxes = bboxtool.rescale_bbox(pred_bboxes, pred_im_size, gt_im_size)

    total_classes = set(pred_classes).union(set(gt_classes))
    recall_step = np.linspace(0, 1, 11)
    len_recall_step = len(recall_step)
    AP_classes = [0 for _ in range(len(total_classes))]
    for c_cnt, c_id in enumerate(total_classes):
        # get bbox for the current class only
        pred_id = np.where(pred_classes == c_id)[0]
        c_pred_bbox = pred_bboxes[pred_id]
        c_pred_conf = pred_conf[pred_id]

        gt_id = np.where(gt_classes == c_id)[0]
        c_gt_bbox = gt_bboxes[gt_id]
        n_gt = len(c_gt_bbox)

        # AP is 0 if this class does not in either prediction or gt
        if len(pred_id) == 0 or len(gt_id) == 0:
            AP_classes[c_cnt] = 0
            continue

        # get corrent detection based on IoUs between prediction and gt
        # IoU_mat [n_gt, n_pred]
        IoU_mat = bboxtool.bbox_list_IOU(c_gt_bbox, c_pred_bbox, align=False)
        det_gt_list = np.argmax(IoU_mat, axis=0)
        iou_list = IoU_mat[det_gt_list, np.arange(len(det_gt_list))]
        iou_list[np.where(iou_list < IoU_thr)] = 0

        # make table of IoU, prediction confidence and detected gt_id for
        # sorting the results based on prediction confidence
        det_table = np.stack((iou_list, c_pred_conf, det_gt_list), axis=-1)
        det_table = det_table[det_table[:, 1].argsort()[::-1]]

        # compute recall and precision for each confidence threshold
        recall_list = [0 for _ in range(len(iou_list))]
        precision_list = [0 for _ in range(len(iou_list))]
        prev_precision = 0.
        TP_id = (det_table[:, 0] > 0)
        peak_list = []
        for i in range(len(iou_list)):
            recall_list[i] = len(set(
                det_gt_list[:i + 1][TP_id[:i + 1]])) / n_gt
            precision_list[i] = sum(det_table[:i + 1, 0] > 0) / (i + 1)
            if precision_list[i] < prev_precision:
                peak_list.append((prev_precision, recall_list[i - 1]))
            prev_precision = precision_list[i]
        peak_list.append((prev_precision, recall_list[-1]))

        # get max precision for each recall level
        max_precision = [0 for _ in range(len_recall_step)]
        peak_p = 0
        max_ = 0
        for idx, recall_ in enumerate(recall_step):
            while peak_p < len(peak_list) and peak_list[peak_p][1] <= recall_:
                max_ = max(max_, peak_list[peak_p][0])
                peak_p += 1
            max_precision[idx] = max_
            if peak_p < len(peak_list):
                max_ = peak_list[peak_p][0]
        max_precision[0] = max(max_precision)
        AP_classes[c_cnt] = np.mean(max_precision)

    return np.mean(AP_classes)