Пример #1
0
 def load_annotations(self, ann_file):
     contents, _ = bt.load_hrsc(img_dir=self.img_prefix,
                                ann_dir=ann_file,
                                classes=self.CLASSES)
     if self.imgset is not None:
         contents = bt.split_imgset(contents, self.imgset)
     return contents
Пример #2
0
def mask2bbox(masks, btype):
    if isinstance(masks, PolygonMasks):
        tran_func = bt.choice_by_type(polymask2hbb, polymask2obb,
                                      polymask2poly, btype)
    elif isinstance(masks, BitmapMasks):
        tran_func = bt.choice_by_type(bitmapmask2hbb, bitmapmask2obb,
                                      bitmapmask2poly, btype)
    else:
        raise NotImplementedError
    return tran_func(masks)
Пример #3
0
 def __init__(self, imgset, classwise, ann_file, img_prefix, *args,
              **kwargs):
     self.imgset = imgset
     if classwise:
         HRSCDataset.CLASSES = bt.get_classes('hrsc_cls')
     else:
         HRSCDataset.CLASSES = bt.get_classes('hrsc')
     super(HRSCDataset, self).__init__(*args,
                                       ann_file=ann_file,
                                       img_prefix=img_prefix,
                                       **kwargs)
Пример #4
0
def main():
    args = parse_args()

    print('Loading ground truth and results information')
    gt_load_func = getattr(bt.datasets, 'load_' + args.gt_type)
    res_load_func = getattr(bt.datasets, 'load_' + args.res_type)
    gt_infos, gt_cls = gt_load_func(img_dir=args.img_dir,
                                    ann_dir=args.gt_ann_dir,
                                    classes=args.classes,
                                    nproc=args.nproc)
    res_infos, res_cls = res_load_func(img_dir=args.img_dir,
                                       ann_dir=args.res_ann_dir,
                                       classes=args.classes,
                                       nproc=args.nproc)
    bt.change_cls_order(res_infos, res_cls, gt_cls)

    print('Parsing ground truth and results information')
    id_mapper = {info['id']: i for i, info in enumerate(res_infos)}
    gts, res = [], []
    for gt_info in gt_infos:
        img_id = gt_info['id']
        res_info = res_infos[id_mapper[img_id]]
        assert 'scores' in res_info['ann'], \
                "f{args.res_type} don't have scores information"

        res_bboxes = res_info['ann']['bboxes']
        res_labels = res_info['ann']['labels']
        res_scores = res_info['ann']['scores']
        res_dets = np.concatenate([res_bboxes, res_scores[..., None]], axis=1)
        res_dets = [res_dets[res_labels == i] for i in range(len(gt_cls))]
        res.append(res_dets)

        gt_bboxes = gt_info['ann']['bboxes']
        gt_labels = gt_info['ann']['labels']
        diffs = gt_info['ann'].get('diffs',
                                   np.zeros(gt_bboxes.shape[0], dtype=np.int))
        gt_ann = {}
        if args.ign_diff > 0:
            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
        gts.append(gt_ann)

    print('Starting calculating mAP')
    bt.eval_map(res,
                gts,
                iou_thr=args.iou_thr,
                use_07_metric=args.voc_metric == '07',
                nproc=args.nproc,
                dataset=gt_cls)
Пример #5
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
Пример #6
0
def get_windows(img_W, img_H, sizes, steps, in_rate_thr=0.6):
    assert 1 >= in_rate_thr >= 0, 'The `in_rate_thr` should lie in 0~1'
    windows = []
    for size, step in zip(sizes, steps):
        assert size > step, 'Size should large than step'

        x_num = 1 if img_W <= size else ceil((img_W - size) / step + 1)
        x_start = [step * i for i in range(x_num)]
        if len(x_start) > 1 and x_start[-1] + size > img_W:
            x_start[-1] = img_W - size

        y_num = 1 if img_H <= size else ceil((img_H - size) / step + 1)
        y_start = [step * i for i in range(y_num)]
        if len(y_start) > 1 and y_start[-1] + size > img_H:
            y_start[-1] = img_H - size

        start = np.array(list(product(x_start, y_start)), dtype=np.int64)
        windows.append(np.concatenate([start, start + size], axis=1))
    windows = np.concatenate(windows, axis=0)

    img_contour = np.array([[0, 0, img_W, img_H]])
    win_iofs = bt.bbox_overlaps(windows, img_contour, mode='iof').reshape(-1)
    if not np.any(win_iofs >= in_rate_thr):
        win_iofs[abs(win_iofs - win_iofs.max()) < 0.01] = 1

    return windows[win_iofs >= in_rate_thr]
Пример #7
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
Пример #8
0
    def get_classes(cls, classes=None):
        if classes is None:
            cls.custom_classes = False
            return cls.CLASSES

        cls.custom_classes = True
        return bt.get_classes(classes)
Пример #9
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
Пример #10
0
    def show_result(self,
                    img,
                    result,
                    colors='green',
                    top_k=300,
                    thickness=1,
                    win_name='',
                    wait_time=0,
                    show=False,
                    out_file=None,
                    score_thr=None):
        img = mmcv.imread(img)
        bboxes, scores = result[:, :-1], result[:, -1]
        idx = scores.argsort()[::-1]
        bboxes = bboxes[idx]

        top_k = min(top_k, len(bboxes))
        bboxes = bboxes[:top_k, :]

        if out_file is not None:
            show = False
        img = bt.imshow_bboxes(
            img,
            bboxes,
            colors=colors,
            thickness=thickness,
            with_text=False,
            show=show,
            win_name=win_name,
            wait_time=wait_time,
            out_file=out_file)
        return img
Пример #11
0
    def base_rotate(self, results, matrix, w, h, img_bound):
        if 'img' in results:
            img = cv2.warpAffine(results['img'], matrix, (w, h))
            results['img'] = img
            results['img_shape'] = img.shape

        if 'gt_masks' in results:
            polygons = switch_mask_type(results['gt_masks'], 'polygon')
            warped_polygons = rotate_polygonmask(polygons, matrix, w, h)

            if self.keep_shape:
                obbs = mask2bbox(warped_polygons, 'obb')
                iofs = bt.bbox_overlaps(obbs, img_bound, mode='iof')
                if_inwindow = iofs[:, 0] > self.keep_iof_thr
                index = np.nonzero(if_inwindow)[0]
                warped_polygons = warped_polygons[index]

            if isinstance(results['gt_masks'], BitmapMasks):
                results['gt_masks'] = switch_mask_type(warped_polygons,
                                                       'bitmap')
            elif isinstance(results['gt_masks'], PolygonMasks):
                results['gt_masks'] = switch_mask_type(warped_polygons,
                                                       'polygon')
            else:
                raise NotImplementedError

            if 'gt_bboxes' in results:
                results['gt_bboxes'] = mask2bbox(warped_polygons, 'hbb')

        elif 'gt_bboxes' in results:
            warped_bboxes = bt.warp(results['gt_bboxes'],
                                    matrix,
                                    keep_type=True)
            if self.keep_shape:
                iofs = bt.bbox_overlaps(warped_bboxes, img_bound, mode='iof')
                if_inwindow = iofs[:, 0] > self.keep_iof_thr
                # if ~if_inwindow.any():
                # return True
                warped_bboxes = warped_bboxes[if_inwindow]
            results['gt_bboxes'] = warped_bboxes

        if 'gt_labels' in results and self.keep_shape:
            results['gt_labels'] = results['gt_labels'][if_inwindow]

        for k in results.get('aligned_fields', []):
            if self.keep_shape:
                results[k] = results[k][if_inwindow]
Пример #12
0
    def __call__(self, results):
        results['rotate_after_flip'] = self.rotate_after_flip
        if 'angle' not in results:
            results['angle'] = self.get_random_angle(results)
        if results['angle'] == 0:
            results['matrix'] = np.eye(3)
            return results
        matrix, w, h = self.get_matrix_and_size(results)
        results['matrix'] = matrix
        img_bound = np.array([[0, 0, w, 0, w, h, 0, h]])
        self.base_rotate(results, matrix, w, h, img_bound)

        for k in results.get('img_fields', []):
            if k != 'img':
                results[k] = cv2.warpAffine(results[k], matrix, (w, h))

        for k in results.get('bbox_fields', []):
            if k == 'gt_bboxes':
                continue
            warped_bboxes = bt.warp(results[k], matrix, keep_type=True)
            if self.keep_shape:
                iofs = bt.bbox_overlaps(warped_bboxes, img_bound, mode='iof')
                warped_bboxes = warped_bboxes[iofs[:, 0] > self.keep_iof_thr]
            results[k] = warped_bboxes

        for k in results.get('mask_fields', []):
            if k == 'gt_masks':
                continue
            polys = switch_mask_type(results[k], 'polygon')
            warped_polys = rotate_polygonmask(polys, matrix, w, h)
            if self.keep_shape:
                obbs = mask2bbox(warped_polys, 'obb')
                iofs = bt.bbox_overlaps(obbs, img_bound, mode='iof')
                index = np.nonzero(iofs[:, 0] > self.keep_iof_thr)[0]
                warped_polys = warped_polys[index]

            if isinstance(results[k], BitmapMasks):
                results[k] = switch_mask_type(warped_polys, 'bitmap')
            elif isinstance(results[k], PolygonMasks):
                results[k] = switch_mask_type(warped_polys, 'polygon')
            else:
                raise NotImplementedError

        for k in results.get('seg_fields', []):
            results[k] = cv2.warpAffine(results[k], matrix, (w, h))

        return results
Пример #13
0
    def format_results(self, results, save_dir=None, **kwargs):
        assert len(results) == len(self.data_infos)
        contents = []
        for result, data_info in zip(results, self.data_infos):
            info = copy.deepcopy(data_info)
            info.pop('ann')

            ann, bboxes, labels, scores = dict(), list(), list(), list()
            for i, dets in enumerate(result):
                bboxes.append(dets[:, :-1])
                scores.append(dets[:, -1])
                labels.append(np.zeros((dets.shape[0], ), dtype=np.int) + i)
            ann['bboxes'] = np.concatenate(bboxes, axis=0)
            ann['labels'] = np.concatenate(labels, axis=0)
            ann['scores'] = np.concatenate(scores, axis=0)
            info['ann'] = ann
            contents.append(info)

        if save_dir is not None:
            bt.save_pkl(save_dir, contents, self.CLASSES)
        return contents
Пример #14
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
Пример #15
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()
Пример #16
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
Пример #17
0
def polymask2obb(masks):
    obbs = []
    for mask in masks:
        all_mask_points = np.concatenate(mask, axis=0).reshape(-1, 2)
        all_mask_points = all_mask_points.astype(np.float32)
        (x, y), (w, h), angle = cv2.minAreaRect(all_mask_points)
        angle = -angle
        theta = angle / 180 * pi
        obbs.append([x, y, w, h, theta])

    if not obbs:
        obbs = np.zeros((0, 5), dtype=np.float32)
    else:
        obbs = np.array(obbs, dtype=np.float32)
    obbs = bt.regular_obb(obbs)
    return obbs
Пример #18
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
Пример #19
0
def eval_arb_recalls(gts,
                     proposals,
                     with_scores=True,
                     proposal_nums=None,
                     iou_thrs=0.5,
                     logger=None):
    """Calculate recalls.

    Args:
        gts (list[ndarray]): a list of arrays of shape (n, 4)
        proposals (list[ndarray]): a list of arrays of shape (k, 4) or (k, 5)
        proposal_nums (int | Sequence[int]): Top N proposals to be evaluated.
        iou_thrs (float | Sequence[float]): IoU thresholds. Default: 0.5.
        logger (logging.Logger | str | None): The way to print the recall
            summary. See `mmdet.utils.print_log()` for details. Default: None.

    Returns:
        ndarray: recalls of different ious and proposal nums
    """

    img_num = len(gts)
    assert img_num == len(proposals)

    proposal_nums, iou_thrs = set_recall_param(proposal_nums, iou_thrs)

    all_ious = []
    for i in range(img_num):
        if proposals[i].ndim == 2 and with_scores:
            scores = proposals[i][:, -1]
            sort_idx = np.argsort(scores)[::-1]
            img_proposal = proposals[i][sort_idx, :]
        else:
            img_proposal = proposals[i]
        if with_scores:
            img_proposal = img_proposal[:, :-1]
        prop_num = min(img_proposal.shape[0], proposal_nums[-1])
        if gts[i] is None or gts[i].shape[0] == 0:
            ious = np.zeros((0, img_proposal.shape[0]), dtype=np.float32)
        else:
            ious = bt.bbox_overlaps(gts[i], img_proposal[:prop_num])
        all_ious.append(ious)
    all_ious = np.array(all_ious)
    recalls = _recalls(all_ious, proposal_nums, iou_thrs)

    print_recall_summary(recalls, proposal_nums, iou_thrs, logger=logger)
    return recalls
Пример #20
0
def get_window_obj(info, windows, iof_thr):
    bboxes = info['ann']['bboxes']
    iofs = bt.bbox_overlaps(bboxes, windows, mode='iof')

    window_anns = []
    for i in range(windows.shape[0]):
        win_iofs = iofs[:, i]
        pos_inds = np.nonzero(win_iofs >= iof_thr)[0].tolist()

        win_ann = dict()
        for k, v in info['ann'].items():
            try:
                win_ann[k] = v[pos_inds]
            except TypeError:
                win_ann[k] = [v[i] for i in pos_inds]
        win_ann['trunc'] = win_iofs[pos_inds] < 1
        window_anns.append(win_ann)
    return window_anns
Пример #21
0
    def __call__(self, results):
        gt_bboxes = results['gt_bboxes']
        if len(gt_bboxes) <= self.n:
            return results

        if 'gt_masks' in results:
            areas = results['gt_masks'].areas
        else:
            areas = bt.bbox_areas(gt_bboxes)

        index = np.argsort(areas)[:self.n]
        results['gt_bboxes'] = gt_bboxes[index]
        if 'gt_labels' in results:
            results['gt_labels'] = results['gt_labels'][index]
        if 'gt_masks' in results:
            results['gt_masks'] = results['gt_masks'][index]

        return results
Пример #22
0
def BT_nms(dets, iou_thr, device_id=None):
    if isinstance(dets, torch.Tensor):
        is_tensor = True
        device = dets.device
        dets_np = dets.cpu().numpy()
    elif isinstance(dets, np.ndarray):
        is_tensor = False
        dets_np = dets
    else:
        raise TypeError('dets must be eithr a Tensor or numpy array, '
                        f'but got {type(dets)}')

    bboxes, scores = dets_np[:, :-1], dets_np[:, -1]
    inds = bt.bbox_nms(bboxes, scores, iou_thr=iou_thr, score_thr=0)

    if is_tensor:
        inds = torch.from_numpy(inds).to(device)
    return dets[inds, :], inds
Пример #23
0
def crop_and_save_img(info, windows, window_anns, img_dir, no_padding,
                      padding_value, filter_empty, save_dir, img_ext):
    img = cv2.imread(osp.join(img_dir, info['filename']))
    patch_infos = []
    for i in range(windows.shape[0]):
        ann = window_anns[i]
        if filter_empty and (ann['bboxes'].size == 0):
            continue

        patch_info = dict()
        for k, v in info.items():
            if k not in ['id', 'fileanme', 'width', 'height', 'ann']:
                patch_info[k] = v

        window = windows[i]
        x_start, y_start, x_stop, y_stop = window.tolist()
        ann['bboxes'] = bt.translate(ann['bboxes'], -x_start, -y_start)
        patch_info['ann'] = ann
        patch_info['x_start'] = x_start
        patch_info['y_start'] = y_start
        patch_info['id'] = info['id'] + f'_{i:04d}'
        patch_info['ori_id'] = info['id']

        patch = img[y_start:y_stop, x_start:x_stop]
        if not no_padding:
            height = y_stop - y_start
            width = x_stop - x_start
            if height > patch.shape[0] or width > patch.shape[1]:
                padding_patch = np.empty((height, width, patch.shape[-1]),
                                         dtype=np.uint8)
                if not isinstance(padding_value, (int, float)):
                    assert len(padding_value) == patch.shape[-1]
                padding_patch[...] = padding_value
                padding_patch[:patch.shape[0], :patch.shape[1], ...] = patch
                patch = padding_patch
        patch_info['height'] = patch.shape[0]
        patch_info['width'] = patch.shape[1]

        cv2.imwrite(osp.join(save_dir, patch_info['id'] + img_ext), patch)
        patch_info['filename'] = patch_info['id'] + img_ext
        patch_infos.append(patch_info)

    return patch_infos
Пример #24
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')
Пример #25
0
def merge_patch_results(results, windows, nms_cfg):
    nms_cfg_ = nms_cfg.copy()
    nms_type = nms_cfg_.pop('type', 'BT_nms')
    try:
        nms_op = getattr(nms_rotated, nms_type)
    except AttributeError:
        nms_op = getattr(nms, nms_type)

    _results = []
    for _cls_result in zip(*results):
        cls_result = []
        for dets, win in zip(_cls_result, windows):
            bboxes, scores = dets[:, :-1], dets[:, [-1]]
            x_start, y_start = win[:2]
            bboxes = bt.translate(bboxes, x_start, y_start)
            cls_result.append(np.concatenate([bboxes, scores], axis=1))

        cls_result = np.concatenate(cls_result, axis=0)
        _result, _ = nms_op(cls_result, **nms_cfg_)
        _results.append(_result)
    return _results
Пример #26
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
Пример #27
0
    def __call__(self, bboxes1, bboxes2, mode='iou', is_aligned=False):
        """Calculate IoU between 2D bboxes

        Args:
            bboxes1 (Tensor): bboxes have shape (m, 4) in <x1, y1, x2, y2>
                format, or shape (m, 5) in <x1, y1, x2, y2, score> format.
            bboxes2 (Tensor): bboxes have shape (m, 4) in <x1, y1, x2, y2>
                format, shape (m, 5) in <x1, y1, x2, y2, score> format, or be
                empty. If is_aligned is ``True``, then m and n must be equal.
            mode (str): "iou" (intersection over union) or iof (intersection
                over foreground).

        Returns:
            ious(Tensor): shape (m, n) if is_aligned == False else shape (m, 1)
        """
        assert bboxes1.size(-1) in [0, 8, 9]
        assert bboxes2.size(-1) in [0, 8, 9]
        if bboxes2.size(-1) == 9:
            bboxes2 = bboxes2[..., :8]
        if bboxes1.size(-1) == 9:
            bboxes1 = bboxes1[..., :8]
        return bt.bbox_overlaps(bboxes1, bboxes2, mode, is_aligned)
Пример #28
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
Пример #29
0
    def __call__(self, results):
        for k in ['gt_bboxes', 'gt_masks', 'gt_labels']:
            if k in results:
                num_objs = len(results[k])
                break
        else:
            return results

        ignore = np.zeros((num_objs, ), dtype=np.bool)
        if self.ignore_diff:
            assert 'diffs' in results
            diffs = results['diffs']
            ignore[diffs == 1] = True

        if self.ignore_truncated:
            assert 'trunc' in results
            trunc = results['trunc']
            ignore[trunc == 1] = True

        if self.ignore_size:
            bboxes = results['gt_bboxes']
            wh = bboxes[:, 2:] - bboxes[:, :2]
            ignore[np.min(wh, axis=1) < self.ignore_size] = True

        if self.ignore_real_scales:
            assert len(self.ignore_real_scales) == (len(results['split_sizes']) *
                                                    len(results['split_rates']))
            polys = mask2bbox(results['gt_masks'], 'poly')
            if 'scale_factor' in results:
                scale_factor = np.tile(results['scale_factor'], 2)
                polys = polys / scale_factor
            bbox_scales = np.sqrt(bt.bbox_areas(polys))

            split_sizes=[]
            for rate in results['split_rates']:
                split_sizes += [int(size / rate) for size in results['split_sizes']]
            img_scale = results['img_info']['width']
            scale_ratio = np.array(split_sizes) / img_scale
            inds = np.argmin(abs(np.log(scale_ratio)))
            min_scale, max_scale = self.ignore_real_scales[inds]
            if min_scale is None:
                min_scale = 0
            if max_scale is None:
                max_scale = np.inf
            ignore[bbox_scales < min_scale] = True
            ignore[bbox_scales > max_scale] = True

        if 'gt_bboxes' in results:
            bboxes = results['gt_bboxes']
            gt_bboxes = bboxes[~ignore]
            gt_bboxes_ignore = bboxes[ignore]

            results['gt_bboxes'] = gt_bboxes
            results['gt_bboxes_ignore'] = gt_bboxes_ignore
            if 'gt_bboxes_ignore' not in results['bbox_fields']:
                results['bbox_fields'].append('gt_bboxes_ignore')

        if 'gt_masks' in results:
            gt_inds = np.nonzero(~ignore)[0]
            ignore_inds = np.nonzero(ignore)[0]

            if isinstance(results['gt_masks'], PolygonMasks) \
               and len(gt_inds) == 0:
                height = results['gt_masks'].height
                width = results['gt_masks'].width
                gt_masks = PolygonMasks([], height, width)
            else:
                gt_masks = results['gt_masks'][gt_inds]

            if isinstance(results['gt_masks'], PolygonMasks) \
               and len(ignore_inds) == 0:
                height = results['gt_masks'].height
                width = results['gt_masks'].width
                gt_masks_ignore = PolygonMasks([], height, width)
            else:
                gt_masks_ignore = results['gt_masks'][ignore_inds]

            results['gt_masks'] = gt_masks
            results['gt_masks_ignore'] = gt_masks_ignore
            if 'gt_masks_ignore' not in results['mask_fields']:
                results['mask_fields'].append('gt_masks_ignore')

        if 'gt_labels' in results:
            results['gt_labels'] = results['gt_labels'][~ignore]

        for k in results.get('aligned_fields', []):
            results[k] = results[k][~ignore]

        return results
Пример #30
0
    def show_result(self,
                    img,
                    result,
                    score_thr=0.3,
                    colors='green',
                    thickness=1.,
                    font_size=10,
                    win_name='',
                    show=False,
                    wait_time=0,
                    out_file=None):

        img = mmcv.imread(img)
        img = img.copy()
        if isinstance(result, tuple):
            bbox_result, segm_result = result
            if isinstance(segm_result, tuple):
                segm_result = segm_result[0]  # ms rcnn
        else:
            bbox_result, segm_result = result, None
        bboxes = np.vstack(bbox_result)
        labels = [
            np.full(bbox.shape[0], i, dtype=np.int32)
            for i, bbox in enumerate(bbox_result)
        ]
        labels = np.concatenate(labels)
        # draw segmentation masks
        if segm_result is not None and len(labels) > 0:  # non empty
            segms = mmcv.concat_list(segm_result)
            inds = np.where(bboxes[:, -1] > score_thr)[0]
            np.random.seed(42)
            color_masks = [
                np.random.randint(0, 256, (1, 3), dtype=np.uint8)
                for _ in range(max(labels) + 1)
            ]
            for i in inds:
                i = int(i)
                color_mask = color_masks[labels[i]]
                mask = segms[i]
                img[mask] = img[mask] * 0.5 + color_mask * 0.5
        # if out_file specified, do not show image in window
        if out_file is not None:
            show = False
        # draw bounding boxes
        bboxes, scores = bboxes[:, :-1], bboxes[:, -1]
        bboxes = bboxes[scores > score_thr]
        labels = labels[scores > score_thr]
        scores = scores[scores > score_thr]
        img = bt.imshow_bboxes(
            img, bboxes, labels, scores,
            class_names=self.CLASSES,
            colors=colors,
            thickness=thickness,
            font_size=font_size,
            win_name=win_name,
            show=show,
            wait_time=wait_time,
            out_file=out_file)

        if not (show or out_file):
            warnings.warn('show==False and out_file is not specified, only '
                          'result image will be returned')
            return img