예제 #1
0
    def test_save_crop_overlapping(self):
        "Save a crop that is partially overlapping the image"
        i = InselectImage(TESTDATA / 'shapes.png')
        temp = tempfile.mkdtemp()
        try:
            # A crop that is partially overlapping the image
            p = Path(temp) / 'overlapping.png'

            i.save_crops([Rect(-0.1, -0.1, 0.4, 0.3)], [p])

            crop = InselectImage(p).array

            # Crop should have this shape
            self.assertEqual((131, 184, 3), crop.shape)

            # Non-intersecting regions should be all zeroes
            self.assertTrue(np.all(0 == crop[0:44, 0:46]))
            self.assertTrue(np.all(0 == crop[0:44, ]))
            self.assertTrue(np.all(0 == crop[:, 0:46]))
            coords = list(i.from_normalised([Rect(-0.1, -0.1, 0.4, 0.3)]))

            expected = i.array[0:87, 0:138, ]

            self.assertTrue(np.all(expected == crop[44:, 46:, ]))
        finally:
            shutil.rmtree(temp)
예제 #2
0
 def test_from_normalised(self):
     "Crops from normalised coordinates are as expected"
     i = InselectImage(TESTDATA / 'shapes.png')
     h, w = i.array.shape[:2]
     boxes = [Rect(0, 0, 1, 1), Rect(0, 0.2, 0.1, 0.8)]
     self.assertEqual([Rect(0, 0, 459, 437), Rect(0, 87, 46, 350)],
                      list(i.from_normalised(boxes)))
예제 #3
0
    def test_comparison(self):
        a = Rect(0, 1, 2, 3)
        self.assertEqual(a, self.R)
        b = Rect(9, 1, 2, 3)
        self.assertNotEqual(b, self.R)

        with self.assertRaises(NotImplementedError):
            a == ''

        with self.assertRaises(NotImplementedError):
            a == Point(1, 1)
예제 #4
0
    def test_set_items(self):
        "Items are set as expected"
        # TODO LH Check field validation
        path = TESTDATA / 'test_segment.inselect'
        doc = InselectDocument.load(path)

        items = [ {'fields': {}, 'rect': Rect(0, 0, 0.5, 0.5)}, ]
        doc.set_items(items)
        self.assertEqual(items, doc.items)

        # Not normalised
        items = [ {'fields': {}, 'rect': Rect(0, 0, 1, 2)}, ]
        self.assertRaises(InselectError, doc.set_items, items)
예제 #5
0
    def test_set_items(self):
        "Items are set as expected"
        # TODO LH Check field validation
        path = TESTDATA / 'shapes.inselect'
        doc = InselectDocument.load(path)

        items = [{'fields': {}, 'rect': Rect(0, 0, 0.5, 0.5)}]
        doc.set_items(items)
        self.assertEqual(items, doc.items)
예제 #6
0
    def test_save_crops(self):
        "Cropped images are as expected"
        i = InselectImage(TESTDATA / 'test_segment.png')
        temp = tempfile.mkdtemp()
        try:
            # A crop that is the entire image
            p = Path(temp) / 'whole.png'
            i.save_crops([Rect(0, 0, 1, 1)], [p])
            self.assertTrue(np.all(i.array == InselectImage(p).array))

            # A crop that is a portion of the image

            # Make sure that existing file is overwritten
            p = Path(temp) / 'partial.png'
            p.open('w')  # File just needs to exist
            i.save_crops([Rect(0.1, 0.2, 0.4, 0.3)], [p])
            expected = i.array[87:218, 45:228]
            self.assertTrue(np.all(expected == InselectImage(p).array))
        finally:
            shutil.rmtree(temp)
예제 #7
0
class TestRect(unittest.TestCase):
    R = Rect(0, 1, 2, 3)

    def test_rect(self):
        self.assertEqual(0, self.R.left)
        self.assertEqual(1, self.R.top)
        self.assertEqual(2, self.R.width)
        self.assertEqual(3, self.R.height)

    def test_iter(self):
        left, top, width, height = self.R
        self.assertEqual([0, 1, 2, 3], [left, top, width, height])

    def test_area(self):
        self.assertEqual(6, self.R.area)

    def test_coordinates(self):
        self.assertEqual(Coordinates(0, 1, 2, 4), self.R.coordinates)

    def test_topleft(self):
        self.assertEqual(Point(0, 1), self.R.topleft)

    def test_bottomright(self):
        self.assertEqual(Point(2, 4), self.R.bottomright)

    def test_x_centre(self):
        self.assertEqual(1, self.R.x_centre)

    def test_y_centre(self):
        self.assertEqual(2.5, self.R.y_centre)

    def test_centre(self):
        self.assertEqual(Point(1, 2.5), self.R.centre)

    def test_padded(self):
        r = Rect(0, 0, 100, 100)
        self.assertEqual(Rect(-10, -10, 120, 120), r.padded(10.0))

    def test_intersect(self):
        a = Rect(-10, -10, 110, 110)
        b = Rect(0, 0, 100, 100)
        self.assertEqual(Rect(0, 0, 100, 100), a.intersect(b))

    def test_comparison(self):
        a = Rect(0, 1, 2, 3)
        self.assertEqual(a, self.R)
        b = Rect(9, 1, 2, 3)
        self.assertNotEqual(b, self.R)

        with self.assertRaises(NotImplementedError):
            a == ''

        with self.assertRaises(NotImplementedError):
            a == Point(1, 1)
예제 #8
0
 def test_save_crops_progress(self):
     "Check values passed to callable of save_crops"
     i = InselectImage(TESTDATA / 'test_segment.png')
     temp = tempfile.mkdtemp()
     try:
         progress = Mock(return_value=None)
         i.save_crops([Rect(0, 0, 1, 1)], [Path(temp) / 'whole.png'],
                      progress)
         progress.assert_called_once_with('Writing crop 1')
     finally:
         shutil.rmtree(temp)
예제 #9
0
    def test_save_crops_read_only_directory(self):
        "Can't write crops to a read-only directory"
        # This case is doing more than simply testing filesystem behavour
        # because it tests the failure code in InselectImage
        temp = tempfile.mkdtemp()
        try:
            make_readonly(temp)

            i = InselectImage(TESTDATA / 'test_segment.png')
            with self.assertRaises(InselectError):
                i.save_crops([Rect(0, 0, 1, 1)], [Path(temp) / 'x.png'])
        finally:
            rmtree_readonly(temp)
예제 #10
0
    def test_save(self):
        "Document save writes items"
        source = TESTDATA / 'test_segment.inselect'
        temp = tempfile.mkdtemp()
        with temp_directory_with_files(TESTDATA / 'test_segment.inselect',
                                       TESTDATA / 'test_segment.png') as tempdir:
            items = [ {'fields': {}, 'rect': Rect(0.1, 0.2, 0.5, 0.5) }, ]

            doc_temp = tempdir / 'test_segment.inselect'
            d = InselectDocument.load(doc_temp)
            d.set_items(items)
            d.save()

            self.assertEqual(items, InselectDocument.load(doc_temp).items)
예제 #11
0
    def test_save_crop_outside(self):
        "Save a crop that is a entirely outside of the image"
        i = InselectImage(TESTDATA / 'shapes.png')
        temp = tempfile.mkdtemp()
        try:
            # A crop that is a entirely outside of the image
            p = Path(temp) / 'outside.png'
            i.save_crops([Rect(-1.5, -5.0, 1.0, 3.0)], [p])

            crop = InselectImage(p).array

            # Crop should have this shape
            self.assertEqual((1311, 459, 3), crop.shape)

            # All of the crop should be all zeroes
            self.assertTrue(np.all(0 == crop))
        finally:
            shutil.rmtree(temp)
예제 #12
0
 def test_save_crops_all_rotated(self):
     "Crops are saved with different rotations"
     i = InselectImage(TESTDATA / 'shapes.png')
     temp = tempfile.mkdtemp()
     try:
         i.save_crops(repeat(Rect(0, 0, 1, 1), 4),
                      (Path(temp) / '{0}.png'.format(n) for n in range(0, 4)),
                      rotation=[0, 90, 180, -90])
         crop = cv2.imread(str(Path(temp) / '0.png'))
         self.assertTrue(np.all(i.array == crop))
         crop = cv2.imread(str(Path(temp) / '1.png'))
         self.assertTrue(np.all(cv2.flip(cv2.transpose(i.array), 1) == crop))
         crop = cv2.imread(str(Path(temp) / '2.png'))
         self.assertTrue(np.all(cv2.flip(i.array, -1) == crop))
         crop = cv2.imread(str(Path(temp) / '3.png'))
         self.assertTrue(np.all(cv2.flip(cv2.transpose(i.array), 0) == crop))
     finally:
         shutil.rmtree(temp)
예제 #13
0
 def test_save_crops_all_rotated90(self):
     "All crops are saved with 90 degrees of clockwise rotation"
     i = InselectImage(TESTDATA / 'shapes.png')
     temp = tempfile.mkdtemp()
     try:
         i.save_crops(repeat(Rect(0, 0, 1, 1), 4),
                      (Path(temp) / '{0}.png'.format(n) for n in range(0, 4)),
                      rotation=90)
         crop = cv2.imread(str(Path(temp) / '0.png'))
         self.assertTrue(np.all(cv2.flip(cv2.transpose(i.array), 1) == crop))
         crop = cv2.imread(str(Path(temp) / '1.png'))
         self.assertTrue(np.all(cv2.flip(cv2.transpose(i.array), 1) == crop))
         crop = cv2.imread(str(Path(temp) / '2.png'))
         self.assertTrue(np.all(cv2.flip(cv2.transpose(i.array), 1) == crop))
         crop = cv2.imread(str(Path(temp) / '3.png'))
         self.assertTrue(np.all(cv2.flip(cv2.transpose(i.array), 1) == crop))
     finally:
         shutil.rmtree(temp)
예제 #14
0
class TestRect(unittest.TestCase):
    R = Rect(0, 1, 2, 3)

    def test_rect(self):
        self.assertEqual(0, self.R.left)
        self.assertEqual(1, self.R.top)
        self.assertEqual(2, self.R.width)
        self.assertEqual(3, self.R.height)
        self.assertRaises(InselectError, Rect,-1, 1, 2, 3)
        self.assertRaises(InselectError, Rect, 0,-1, 2, 3)
        self.assertRaises(InselectError, Rect, 0, 1, 0, 3)
        self.assertRaises(InselectError, Rect, 0, 1, 2, 0)

    def test_iter(self):
        left, top, width, height = self.R
        self.assertEqual([0, 1, 2, 3], [left, top, width, height])

    def test_area(self):
        self.assertEqual(6, self.R.area)

    def test_coordinates(self):
        self.assertEqual(Coordinates(0, 1, 2, 4), self.R.coordinates)

    def test_topleft(self):
        self.assertEqual(Point(0, 1), self.R.topleft)

    def test_bottomright(self):
        self.assertEqual(Point(2, 4), self.R.bottomright)

    def test_centre(self):
        self.assertEqual(Point(1, 2), self.R.centre)

    def test_comparison(self):
        a = Rect(0, 1, 2, 3)
        self.assertEqual(a, self.R)
        b = Rect(9, 1, 2, 3)
        self.assertNotEqual(b, self.R)

        with self.assertRaises(NotImplementedError):
            a == ''

        with self.assertRaises(NotImplementedError):
            a == Point(1,1)
예제 #15
0
    def test_save_crop_partial(self):
        "Save a crop that is a portion of the image"
        i = InselectImage(TESTDATA / 'shapes.png')
        temp = tempfile.mkdtemp()
        try:
            # A crop that is a portion of the image
            p = Path(temp) / 'partial.png'
            i.save_crops([Rect(0.1, 0.2, 0.4, 0.3)], [p])

            crop = InselectImage(p).array

            # Crop should have this shape
            self.assertEqual((131, 184, 3), crop.shape)

            # Crop should have these pixels
            expected = i.array[87:218, 46:230]
            self.assertTrue(np.all(expected == InselectImage(p).array))
        finally:
            shutil.rmtree(temp)
예제 #16
0
    def test_save(self):
        "Save document"
        with temp_directory_with_files(TESTDATA / 'shapes.inselect',
                                       TESTDATA / 'shapes.png') as tempdir:
            items = [{
                'fields': {
                    'type': 'インセクト'
                },
                'rect': Rect(0.1, 0.2, 0.5, 0.5),
            }]

            doc_temp = tempdir / 'shapes.inselect'
            d = InselectDocument.load(doc_temp)
            d.set_items(items)
            d.save()

            self.assertEqual(items, InselectDocument.load(doc_temp).items)

            # Saved on time should be within last 2 seconds
            now = datetime.now(pytz.timezone("UTC"))
            saved_on = d.properties['Saved on']
            self.assertLessEqual((now - saved_on).seconds, 2)
예제 #17
0
    def test_overwrite_existing_crop(self):
        "Overwrite an existing file with a crop that is the entire image"
        i = InselectImage(TESTDATA / 'shapes.png')
        temp = tempfile.mkdtemp()
        try:
            p = Path(temp) / 'whole.png'

            # Create an image that is all black
            self.assertTrue(cv2.imwrite(str(p),
                            np.zeros((500, 500, 3), dtype='uint8')))

            # A crop that is the entire image
            i.save_crops([Rect(0, 0, 1, 1)], [p])

            crop = InselectImage(p).array

            # Crop should be the same shape as the image
            self.assertEqual(i.array.shape, crop.shape)

            # Crop should have the same pixels as the image
            self.assertTrue(np.all(i.array == crop))
        finally:
            shutil.rmtree(temp)
예제 #18
0
 def to_normalised(self, boxes):
     self.validate_in_bounds(boxes)
     h, w = self.array.shape[:2]
     for left, top, width, height in boxes:
         yield Rect(float(left)/w, float(top)/h, float(width)/w,
                    float(height)/h)
예제 #19
0
 def test_intersect(self):
     a = Rect(-10, -10, 110, 110)
     b = Rect(0, 0, 100, 100)
     self.assertEqual(Rect(0, 0, 100, 100), a.intersect(b))
예제 #20
0
 def test_padded(self):
     r = Rect(0, 0, 100, 100)
     self.assertEqual(Rect(-10, -10, 120, 120), r.padded(10.0))
예제 #21
0
 def test_validate_normalised(self):
     validate_normalised([Rect(0,0,1,1)])
     self.assertRaises(InselectError, validate_normalised, [(-0.1, 0,    1,   1)])
     self.assertRaises(InselectError, validate_normalised, [( 0,  -0.1,  1,   1)])
     self.assertRaises(InselectError, validate_normalised, [( 0,   0,    1.1, 1)])
     self.assertRaises(InselectError, validate_normalised, [( 0,   0,    1,   1.1)])
예제 #22
0
 def test_to_normalised(self):
     i = InselectImage(TESTDATA / 'test_segment.png')
     boxes = [Rect(0, 0, 459, 437), Rect(0, 0, 153, 23)]
     self.assertEqual(
         [Rect(0, 0, 1, 1), Rect(0, 0, 1.0 / 3, 1.0 / 19)],
         list(i.to_normalised(boxes)))
예제 #23
0
 def test_not_normalised(self):
     i = InselectImage(TESTDATA / 'test_segment.png')
     self.assertRaises(i.from_normalised([Rect(0, 0, 2, 2)]))
예제 #24
0
 def from_normalised(self, boxes):
     validate_normalised(boxes)
     h, w = self.array.shape[:2]
     for left, top, width, height in boxes:
         yield Rect(int(w*left), int(h*top), int(w*width), int(h*height))
예제 #25
0
 def test_crops_bad_rotation(self):
     "Generate crops with an illegal rotation"
     i = InselectImage(TESTDATA / 'shapes.png')
     # Need to use context manager because i.crops is a generator function
     with self.assertRaises(ValueError):
         list(i.crops([Rect(0, 0, 1, 1)], -1))