Exemplo n.º 1
0
    def _calc_inner_crop(self):
        """
        Given a rectangle of self.src_imsize HxW that has been rotated by
        self.angle_degrees_ccw (in degrees), computes the location of the
        largest possible axis-aligned rectangle within the rotated rectangle.
        """

        # TODO This needs significant streamlinig.
        a_ccw = np.deg2rad(self.angle_degrees_ccw)
        quadrant = math.floor(a_ccw / (math.pi / 2)) & 3
        sign_alpha = a_ccw if ((quadrant & 1) == 0) else math.pi - a_ccw
        alpha = (sign_alpha % math.pi + math.pi) % math.pi

        h, w = self.src_imsize
        bb_w = w * math.cos(alpha) + h * math.sin(alpha)
        bb_h = w * math.sin(alpha) + h * math.cos(alpha)

        gamma = math.atan2(bb_w, bb_w) if (w < h) else math.atan2(bb_w, bb_w)

        delta = math.pi - alpha - gamma

        length = h if (w < h) else w

        d = length * math.cos(alpha)
        a = d * math.sin(alpha) / math.sin(delta)

        y = a * math.cos(gamma)
        x = y * math.tan(gamma)

        largest_w, largest_h = bb_w - 2 * x, bb_h - 2 * y

        new_h, new_w = self.new_imsize
        left = round((new_w - largest_w) * 0.5)
        right = round((new_w + largest_w) * 0.5)
        top = round((new_h - largest_h) * 0.5)
        bottom = round((new_h + largest_h) * 0.5)
        some_inner_crop = Rectangle(top, left, bottom, right)
        new_img_bbox = Rectangle(0, 0, self.new_imsize[0] - 1,
                                 self.new_imsize[1] - 1)
        self.inner_crop = new_img_bbox.crop(some_inner_crop)[0]
Exemplo n.º 2
0
class RectangleTest(unittest.TestCase):
    def setUp(self):
        self.rect = Rectangle(top=5, left=10, bottom=30, right=30)

    def assertRectEquals(self, rect, top, left, bottom, right):
        self.assertIsInstance(rect, Rectangle)
        self.assertEqual(rect.top, top)
        self.assertEqual(rect.left, left)
        self.assertEqual(rect.bottom, bottom)
        self.assertEqual(rect.right, right)

    def test_empty_crop(self):
        crop_rect = Rectangle(100, 100, 200, 200)
        res_geoms = self.rect.crop(crop_rect)
        self.assertEqual(len(res_geoms), 0)

    def test_crop(self):
        crop_rect = Rectangle(0, 0, 100, 100)
        res_geoms = self.rect.crop(crop_rect)
        self.assertEqual(len(res_geoms), 1)
        res_rect = res_geoms[0]
        self.assertRectEquals(res_rect, self.rect.top, self.rect.left,
                              self.rect.bottom, self.rect.right)

    def test_relative_crop(self):
        crop_rect = Rectangle(3, 4, 100, 100)
        res_geoms = self.rect.relative_crop(crop_rect)
        self.assertEqual(len(res_geoms), 1)
        res_rect = res_geoms[0]
        self.assertRectEquals(res_rect, 2, 6, 27, 26)

    def test_rotate(self):
        imsize = (101, 101)
        rotator = ImageRotator(imsize=imsize, angle_degrees_ccw=90)
        res_rect = self.rect.rotate(rotator)
        self.assertRectEquals(res_rect, 70, 5, 90, 30)

    def test_resize(self):
        in_size = (100, 100)
        out_size = (200, 150)
        res_rect = self.rect.resize(in_size, out_size)
        self.assertRectEquals(res_rect, 10, 15, 60, 45)

    def test_scale(self):
        factor = 1.3
        res_rect = self.rect.scale(factor)
        self.assertRectEquals(res_rect, 6, 13, 39, 39)

    def test_translate(self):
        drows = 8
        dcols = 259
        res_rect = self.rect.translate(drows, dcols)
        self.assertRectEquals(res_rect, 13, 269, 38, 289)

    def test_fliplr(self):
        im_size = (100, 200)
        res_rect = self.rect.fliplr(im_size)
        self.assertRectEquals(res_rect, 5, 170, 30, 190)

    def test_flipud(self):
        im_size = (100, 200)
        res_rect = self.rect.flipud(im_size)
        self.assertRectEquals(res_rect, 70, 10, 95, 30)

    def test_area(self):
        area = self.rect.area
        self.assertIsInstance(area, float)
        self.assertEqual(area, 546.0)

    def test_to_bbox(self):
        res_rect = self.rect.to_bbox()
        self.assertRectEquals(res_rect, self.rect.top, self.rect.left,
                              self.rect.bottom, self.rect.right)

    def test_clone(self):
        res_rect = self.rect.clone()
        self.assertRectEquals(res_rect, self.rect.top, self.rect.left,
                              self.rect.bottom, self.rect.right)
        self.assertIsNot(res_rect, self.rect)

    def test_from_json(self):
        packed_obj = {
            'some_stuff': 'aaa',
            POINTS: {
                EXTERIOR: [[17, 3], [34, 45]],
                INTERIOR: []
            }
        }
        res_rect = Rectangle.from_json(packed_obj)
        self.assertRectEquals(res_rect, 3, 17, 45, 34)

    def test_to_json(self):
        res_obj = self.rect.to_json()
        expected_dict = {POINTS: {EXTERIOR: [[10, 5], [30, 30]], INTERIOR: []}}
        self.assertDictEqual(res_obj, expected_dict)

    def test_draw(self):
        rect = Rectangle(1, 1, 3, 3)

        bitmap_1 = np.zeros((5, 5), dtype=np.uint8)
        rect.draw_contour(bitmap_1, 1)
        expected_mask_1 = np.array(
            [[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, 0, 1, 0],
             [0, 1, 1, 1, 0], [0, 0, 0, 0, 0]],
            dtype=np.uint8)
        self.assertTrue(np.array_equal(bitmap_1, expected_mask_1))

        bitmap_2 = np.zeros((5, 5), dtype=np.uint8)
        rect.draw(bitmap_2, 1)
        expected_mask_2 = np.array(
            [[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0],
             [0, 1, 1, 1, 0], [0, 0, 0, 0, 0]],
            dtype=np.uint8)
        self.assertTrue(np.array_equal(bitmap_2, expected_mask_2))