Пример #1
0
def polymask2poly(masks):
    polys = []
    for mask in masks:
        all_mask_points = np.concatenate(mask, axis=0)[None, :]
        if all_mask_points.size != 8:
            all_mask_points = bt.bbox2type(all_mask_points, 'obb')
            all_mask_points = bt.bbox2type(all_mask_points, 'poly')
        polys.append(all_mask_points)

    if not polys:
        polys = np.zeros((0, 8), dtype=np.float32)
    else:
        polys = np.concatenate(polys, axis=0)
    return polys
Пример #2
0
def bbox2mask(bboxes, w, h, mask_type='polygon'):
    polys = bt.bbox2type(bboxes, 'poly')
    assert mask_type in ['polygon', 'bitmap']
    if mask_type == 'bitmap':
        masks = []
        for poly in polys:
            rles = maskUtils.frPyObjects([poly.tolist()], h, w)
            masks.append(maskUtils.decode(rles[0]))
        gt_masks = BitmapMasks(masks, h, w)

    else:
        gt_masks = PolygonMasks([[poly] for poly in polys], h, w)
    return gt_masks
Пример #3
0
    def _load_bboxes(self, results):
        ann_info = results['ann_info']
        gt_bboxes = ann_info['bboxes'].copy()
        results['gt_bboxes'] = bt.bbox2type(gt_bboxes, 'hbb')
        results['bbox_fields'].append('gt_bboxes')

        if self.obb_as_mask:
            MaskClass = PolygonMasks if self.bbox_mtype == 'polygon' \
                    else BitmapMasks
            h, w = results['img_info']['height'], results['img_info']['width']
            results['gt_masks'] = bbox2mask(gt_bboxes, w, h, self.bbox_mtype)
            results['gt_masks_ignore'] = MaskClass([], h, w)
            results['mask_fields'].append('gt_masks')
        return results
Пример #4
0
    def get_matrix_and_size(self, results):
        angle = results['angle']
        height, width = results['img_shape'][:2]
        if self.keep_shape:
            center = ((width - 1) * 0.5, (height - 1) * 0.5)
            matrix = cv2.getRotationMatrix2D(center, angle, 1)
        else:
            matrix = cv2.getRotationMatrix2D((0, 0), angle, 1)
            img_bbox = np.array([[0, 0, width, 0, width, height, 0, width]])
            img_bbox = bt.bbox2type(bt.warp(img_bbox, matrix), 'hbb')

            width = int(img_bbox[0, 2] - img_bbox[0, 0] + 1)
            height = int(img_bbox[0, 3] - img_bbox[0, 1] + 1)
            matrix[0, 2] = -img_bbox[0, 0]
            matrix[1, 2] = -img_bbox[0, 1]
        return matrix, width, height
Пример #5
0
def _merge_func(info, CLASSES, iou_thr, task):
    img_id, label_dets = info
    label_dets = np.concatenate(label_dets, axis=0)
    labels, dets = label_dets[:, 0], label_dets[:, 1:]
    nms_ops = bt.choice_by_type(nms, obb_nms, BT_nms, dets, with_score=True)

    big_img_results = []
    for i in range(len(CLASSES)):
        cls_dets = dets[labels == i]
        nms_dets, _ = nms_ops(cls_dets, iou_thr)

        if task == 'Task2':
            bboxes = bt.bbox2type(nms_dets[:, :-1], 'hbb')
            nms_dets = np.concatenate([bboxes, nms_dets[:, -1:]], axis=1)
        big_img_results.append(nms_dets)
    return img_id, big_img_results
Пример #6
0
 def _proposal2json(self, results):
     """Convert proposal results to COCO json style"""
     json_results = []
     for idx in range(len(self)):
         img_id = self.img_ids[idx]
         bboxes = results[idx]
         bboxes, scores = bboxes[:, :-1], bboxes[:, [-1]]
         bboxes = bt.bbox2type(bboxes, 'hbb')
         bboxes = np.concatenate([bboxes, scores], axis=1)
         for i in range(bboxes.shape[0]):
             data = dict()
             data['image_id'] = img_id
             data['bbox'] = self.xyxy2xywh(bboxes[i])
             data['score'] = float(bboxes[i][4])
             data['category_id'] = 1
             json_results.append(data)
     return json_results
Пример #7
0
def bitmapmask2poly(masks):
    if len(masks) == 0:
        return np.zeros((0, 8), dtype=np.float32)

    height, width = masks.height, masks.width
    x, y = np.arange(width), np.arange(height)
    xx, yy = np.meshgrid(x, y)
    coors = np.stack([xx, yy], axis=-1)
    coors = coors.astype(np.float32)

    obbs = []
    for mask in masks:
        points = coors[mask == 1]
        (x, y), (w, h), angle = cv2.minAreaRect(points)
        angle = -angle
        theta = angle / 180 * pi
        obbs.append([x, y, w, h, theta])

    obbs = np.array(obbs, dtype=np.float32)
    return bt.bbox2type(obbs, 'poly')
Пример #8
0
    def _segm2json(self, results):
        """Convert instance segmentation results to COCO json style"""
        bbox_json_results = []
        segm_json_results = []
        for idx in range(len(self)):
            img_id = self.img_ids[idx]
            det, seg = results[idx]
            for label in range(len(det)):
                # bbox results
                bboxes = det[label]
                bboxes, scores = bboxes[:, :-1], bboxes[:, [-1]]
                bboxes = bt.bbox2type(bboxes, 'hbb')
                bboxes = np.concatenate([bboxes, scores], axis=1)
                for i in range(bboxes.shape[0]):
                    data = dict()
                    data['image_id'] = img_id
                    data['bbox'] = self.xyxy2xywh(bboxes[i])
                    data['score'] = float(bboxes[i][4])
                    data['category_id'] = self.cat_ids[label]
                    bbox_json_results.append(data)

                # segm results
                # some detectors use different scores for bbox and mask
                if isinstance(seg, tuple):
                    segms = seg[0][label]
                    mask_score = seg[1][label]
                else:
                    segms = seg[label]
                    mask_score = [bbox[4] for bbox in bboxes]
                for i in range(bboxes.shape[0]):
                    data = dict()
                    data['image_id'] = img_id
                    data['score'] = float(mask_score[i])
                    data['category_id'] = self.cat_ids[label]
                    if isinstance(segms[i]['counts'], bytes):
                        segms[i]['counts'] = segms[i]['counts'].decode()
                    data['segmentation'] = segms[i]
                    segm_json_results.append(data)
        return bbox_json_results, segm_json_results
Пример #9
0
def single_vis(task, btype, class_names, colors, thickness, text_off,
               font_size, show_off, wait_time, lock, prog, total):
    imgpath, out_file, bboxes, labels, scores = task
    bboxes = bt.bbox2type(bboxes, btype) if btype else bboxes
    bt.imshow_bboxes(imgpath,
                     bboxes,
                     labels,
                     scores,
                     class_names=class_names,
                     colors=colors,
                     thickness=thickness,
                     with_text=(not text_off),
                     font_size=font_size,
                     show=(not show_off),
                     wait_time=wait_time,
                     out_file=out_file)

    lock.acquire()
    prog.value += 1
    msg = f'({prog.value/total:3.1%} {prog.value}:{total})'
    msg += ' - ' + f"Filename: {osp.split(imgpath)[-1]}"
    print(msg)
    lock.release()
Пример #10
0
def _list_mask_2_obb(dets, segments):
    new_dets = []
    for cls_dets, cls_segments in zip(dets, segments):
        new_cls_dets = []
        for ds, segs in zip(cls_dets, cls_segments):
            _, scores = ds[:, :-1], ds[:, -1]
            new_bboxes = []
            for seg in segs:
                try:
                    contours, _ = cv2.findContours(seg, cv2.RETR_EXTERNAL,
                                                   cv2.CHAIN_APPROX_NONE)
                except ValueError:
                    _, contours, _ = cv2.findContours(seg, cv2.RETR_EXTERNAL,
                                                      cv2.CHAIN_APPROX_NONE)

                max_contour = max(contours, key=len).reshape(1, -1)
                new_bboxes.append(bt.bbox2type(max_contour, 'obb'))

            new_bboxes = np.zeros((0, 5)) if not new_bboxes else \
                np.concatenate(new_bboxes, axis=0)
            new_cls_dets.append(
                np.concatenate([new_bboxes, scores[:, None]], axis=1))
        new_dets.append(new_cls_dets)
    return new_dets
Пример #11
0
    def evaluate(self,
                 results,
                 metric='mAP',
                 logger=None,
                 with_merge=True,
                 ign_diff=True,
                 ign_scale_ranges=None,
                 save_dir=None,
                 merge_iou_thr=0.1,
                 use_07_metric=True,
                 scale_ranges=None,
                 eval_iou_thr=[0.5],
                 proposal_nums=(2000, ),
                 nproc=10):
        nproc = min(nproc, os.cpu_count())
        if not isinstance(metric, str):
            assert len(metric) == 1
            metric = metric[0]
        allowed_metrics = ['mAP', 'recall']
        if metric not in allowed_metrics:
            raise KeyError(f'metric {metric} is not supported')
        task = self.task

        eval_results = {}
        if metric == 'mAP':
            merged_results = self.format_results(
                results,
                nproc=nproc,
                with_merge=with_merge,
                ign_scale_ranges=ign_scale_ranges,
                iou_thr=merge_iou_thr,
                save_dir=save_dir)

            infos = self.ori_infos if with_merge else self.data_infos
            id_mapper = {ann['id']: i for i, ann in enumerate(infos)}
            det_results, annotations = [], []
            for k, v in merged_results:
                det_results.append(v)
                ann = infos[id_mapper[k]]['ann']
                gt_bboxes = ann['bboxes']
                gt_labels = ann['labels']
                diffs = ann.get('diffs',
                                np.zeros((gt_bboxes.shape[0], ), dtype=np.int))

                if task == 'Task2':
                    gt_bboxes = bt.bbox2type(gt_bboxes, 'hbb')

                gt_ann = {}
                if ign_diff:
                    gt_ann['bboxes_ignore'] = gt_bboxes[diffs == 1]
                    gt_ann['labels_ignore'] = gt_labels[diffs == 1]
                    gt_bboxes = gt_bboxes[diffs == 0]
                    gt_labels = gt_labels[diffs == 0]
                gt_ann['bboxes'] = gt_bboxes
                gt_ann['labels'] = gt_labels
                annotations.append(gt_ann)

            print('\nStart calculate mAP!!!')
            print('Result is Only for reference,',
                  'final result is subject to DOTA_devkit')
            mean_ap, _ = eval_arb_map(det_results,
                                      annotations,
                                      scale_ranges=scale_ranges,
                                      iou_thr=eval_iou_thr,
                                      use_07_metric=use_07_metric,
                                      dataset=self.CLASSES,
                                      logger=logger,
                                      nproc=nproc)
            eval_results['mAP'] = mean_ap
        elif metric == 'recall':
            assert mmcv.is_list_of(results, np.ndarray)
            gt_bboxes = []
            for info in self.data_infos:
                bboxes = info['ann']['bboxes']
                if ign_diff:
                    diffs = info['ann'].get(
                        'diffs', np.zeros((bboxes.shape[0], ), dtype=np.int))
                    bboxes = bboxes[diffs == 0]
                gt_bboxes.append(bboxes)
            if isinstance(eval_iou_thr, float):
                eval_iou_thr = [eval_iou_thr]
            recalls = eval_arb_recalls(gt_bboxes,
                                       results,
                                       True,
                                       proposal_nums,
                                       eval_iou_thr,
                                       logger=logger)
            for i, num in enumerate(proposal_nums):
                for j, iou in enumerate(eval_iou_thr):
                    eval_results[f'recall@{num}@{iou}'] = recalls[i, j]
            if recalls.shape[1] > 1:
                ar = recalls.mean(axis=1)
                for i, num in enumerate(proposal_nums):
                    eval_results[f'AR@{num}'] = ar[i]
        return eval_results