Пример #1
0
    def crop_bboxes(self, bboxes, canvas_bbox):
        kept_bboxes = []
        kept_inx = []
        canvas_poly = eval_utils.box2polygon(canvas_bbox)
        tl = canvas_bbox[0:2]

        for idx, bbox in enumerate(bboxes):
            poly = eval_utils.box2polygon(bbox)
            area, inters = eval_utils.poly_intersection(poly,
                                                        canvas_poly,
                                                        return_poly=True)
            if area == 0:
                continue
            xmin, ymin, xmax, ymax = inters.bounds
            kept_bboxes += [
                np.array(
                    [xmin - tl[0], ymin - tl[1], xmax - tl[0], ymax - tl[1]],
                    dtype=np.float32)
            ]
            kept_inx += [idx]

        if len(kept_inx) == 0:
            return np.array([]).astype(np.float32).reshape(0, 4), kept_inx

        return np.stack(kept_bboxes), kept_inx
Пример #2
0
def test_poly_intersection():

    # test unsupported type
    with pytest.raises(AssertionError):
        utils.poly_intersection(0, 1)

    # test non-overlapping polygons

    points = [0, 0, 0, 1, 1, 1, 1, 0]
    points1 = [10, 20, 30, 40, 50, 60, 70, 80]
    poly = utils.points2polygon(points)
    poly1 = utils.points2polygon(points1)

    area_inters, _ = utils.poly_intersection(poly, poly1)

    assert area_inters == 0

    # test overlapping polygons
    area_inters, _ = utils.poly_intersection(poly, poly)
    assert area_inters == 1
Пример #3
0
    def random_crop_flip(self, results):
        image = results['img']
        polygons = results['gt_masks'].masks
        ignore_polygons = results['gt_masks_ignore'].masks
        all_polygons = polygons + ignore_polygons
        if len(polygons) == 0:
            return results

        if np.random.random() >= self.crop_ratio:
            return results

        h, w, _ = results['img_shape']
        area = h * w
        pad_h = int(h * self.pad_ratio)
        pad_w = int(w * self.pad_ratio)
        h_axis, w_axis = self.generate_crop_target(image, all_polygons, pad_h,
                                                   pad_w)
        if len(h_axis) == 0 or len(w_axis) == 0:
            return results

        attempt = 0
        while attempt < 10:
            attempt += 1
            polys_keep = []
            polys_new = []
            ign_polys_keep = []
            ign_polys_new = []
            xx = np.random.choice(w_axis, size=2)
            xmin = np.min(xx) - pad_w
            xmax = np.max(xx) - pad_w
            xmin = np.clip(xmin, 0, w - 1)
            xmax = np.clip(xmax, 0, w - 1)
            yy = np.random.choice(h_axis, size=2)
            ymin = np.min(yy) - pad_h
            ymax = np.max(yy) - pad_h
            ymin = np.clip(ymin, 0, h - 1)
            ymax = np.clip(ymax, 0, h - 1)
            if (xmax - xmin) * (ymax - ymin) < area * self.min_area_ratio:
                # area too small
                continue

            pts = np.stack([[xmin, xmax, xmax, xmin],
                            [ymin, ymin, ymax, ymax]]).T.astype(np.int32)
            pp = plg(pts)
            fail_flag = False
            for polygon in polygons:
                ppi = plg(polygon[0].reshape(-1, 2))
                ppiou = eval_utils.poly_intersection(ppi, pp)
                if np.abs(ppiou - float(ppi.area)) > self.epsilon and \
                        np.abs(ppiou) > self.epsilon:
                    fail_flag = True
                    break
                elif np.abs(ppiou - float(ppi.area)) < self.epsilon:
                    polys_new.append(polygon)
                else:
                    polys_keep.append(polygon)

            for polygon in ignore_polygons:
                ppi = plg(polygon[0].reshape(-1, 2))
                ppiou = eval_utils.poly_intersection(ppi, pp)
                if np.abs(ppiou - float(ppi.area)) > self.epsilon and \
                        np.abs(ppiou) > self.epsilon:
                    fail_flag = True
                    break
                elif np.abs(ppiou - float(ppi.area)) < self.epsilon:
                    ign_polys_new.append(polygon)
                else:
                    ign_polys_keep.append(polygon)

            if fail_flag:
                continue
            else:
                break

        cropped = image[ymin:ymax, xmin:xmax, :]
        select_type = np.random.randint(3)
        if select_type == 0:
            img = np.ascontiguousarray(cropped[:, ::-1])
        elif select_type == 1:
            img = np.ascontiguousarray(cropped[::-1, :])
        else:
            img = np.ascontiguousarray(cropped[::-1, ::-1])
        image[ymin:ymax, xmin:xmax, :] = img
        results['img'] = image

        if len(polys_new) + len(ign_polys_new) != 0:
            height, width, _ = cropped.shape
            if select_type == 0:
                for idx, polygon in enumerate(polys_new):
                    poly = polygon[0].reshape(-1, 2)
                    poly[:, 0] = width - poly[:, 0] + 2 * xmin
                    polys_new[idx] = [poly.reshape(-1, )]
                for idx, polygon in enumerate(ign_polys_new):
                    poly = polygon[0].reshape(-1, 2)
                    poly[:, 0] = width - poly[:, 0] + 2 * xmin
                    ign_polys_new[idx] = [poly.reshape(-1, )]
            elif select_type == 1:
                for idx, polygon in enumerate(polys_new):
                    poly = polygon[0].reshape(-1, 2)
                    poly[:, 1] = height - poly[:, 1] + 2 * ymin
                    polys_new[idx] = [poly.reshape(-1, )]
                for idx, polygon in enumerate(ign_polys_new):
                    poly = polygon[0].reshape(-1, 2)
                    poly[:, 1] = height - poly[:, 1] + 2 * ymin
                    ign_polys_new[idx] = [poly.reshape(-1, )]
            else:
                for idx, polygon in enumerate(polys_new):
                    poly = polygon[0].reshape(-1, 2)
                    poly[:, 0] = width - poly[:, 0] + 2 * xmin
                    poly[:, 1] = height - poly[:, 1] + 2 * ymin
                    polys_new[idx] = [poly.reshape(-1, )]
                for idx, polygon in enumerate(ign_polys_new):
                    poly = polygon[0].reshape(-1, 2)
                    poly[:, 0] = width - poly[:, 0] + 2 * xmin
                    poly[:, 1] = height - poly[:, 1] + 2 * ymin
                    ign_polys_new[idx] = [poly.reshape(-1, )]
            polygons = polys_keep + polys_new
            ignore_polygons = ign_polys_keep + ign_polys_new
            results['gt_masks'] = PolygonMasks(polygons, *(image.shape[:2]))
            results['gt_masks_ignore'] = PolygonMasks(ignore_polygons,
                                                      *(image.shape[:2]))

        return results
Пример #4
0
def test_poly_intersection():

    # test unsupported type
    with pytest.raises(AssertionError):
        utils.poly_intersection(0, 1)

    # test non-overlapping polygons

    points = [0, 0, 0, 1, 1, 1, 1, 0]
    points1 = [10, 20, 30, 40, 50, 60, 70, 80]
    points2 = [0, 0, 0, 0, 0, 0, 0, 0]  # Invalid polygon
    points3 = [0, 0, 0, 1, 1, 0, 1, 1]  # Self-intersected polygon
    points4 = [0.5, 0, 1.5, 0, 1.5, 1, 0.5, 1]
    poly = utils.points2polygon(points)
    poly1 = utils.points2polygon(points1)
    poly2 = utils.points2polygon(points2)
    poly3 = utils.points2polygon(points3)
    poly4 = utils.points2polygon(points4)

    area_inters = utils.poly_intersection(poly, poly1)

    assert area_inters == 0

    # test overlapping polygons
    area_inters = utils.poly_intersection(poly, poly)
    assert area_inters == 1
    area_inters = utils.poly_intersection(poly, poly4)
    assert area_inters == 0.5

    # test invalid polygons
    assert utils.poly_intersection(poly2, poly2) == 0
    assert utils.poly_intersection(poly3, poly3, invalid_ret=1) == 1
    # The return value depends on the implementation of the package
    assert utils.poly_intersection(poly3, poly3, invalid_ret=None) == 0.25

    # test poly return
    _, poly = utils.poly_intersection(poly, poly4, return_poly=True)
    assert isinstance(poly, Polygon)
    _, poly = utils.poly_intersection(
        poly3, poly3, invalid_ret=None, return_poly=True)
    assert isinstance(poly, Polygon)
    _, poly = utils.poly_intersection(
        poly2, poly3, invalid_ret=1, return_poly=True)
    assert poly is None