| |
| import copy |
| import unittest.mock as mock |
|
|
| import numpy as np |
| import pytest |
| import torchvision.transforms as TF |
| from mmdet.core import BitmapMasks, PolygonMasks |
| from PIL import Image |
|
|
| import mmocr.datasets.pipelines.transforms as transforms |
|
|
|
|
| @mock.patch('%s.transforms.np.random.random_sample' % __name__) |
| @mock.patch('%s.transforms.np.random.randint' % __name__) |
| def test_random_crop_instances(mock_randint, mock_sample): |
|
|
| img_gt = np.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 1, 1], |
| [0, 0, 1, 1, 1], [0, 0, 1, 1, 1]]) |
| |
| mock_sample.side_effect = [1] |
| rci = transforms.RandomCropInstances(6, instance_key='gt_kernels') |
| (i, j) = rci.sample_offset(img_gt, (5, 5)) |
| assert i == 0 |
| assert j == 0 |
|
|
| |
|
|
| rci = transforms.RandomCropInstances(3, instance_key='gt_kernels') |
| mock_sample.side_effect = [1] |
| mock_randint.side_effect = [1, 2] |
| (i, j) = rci.sample_offset(img_gt, (5, 5)) |
| assert i == 1 |
| assert j == 2 |
|
|
| mock_sample.side_effect = [1] |
| mock_randint.side_effect = [1, 2] |
| rci = transforms.RandomCropInstances(5, instance_key='gt_kernels') |
| (i, j) = rci.sample_offset(img_gt, (5, 5)) |
| assert i == 0 |
| assert j == 0 |
|
|
| |
|
|
| rci = transforms.RandomCropInstances(3, instance_key='gt_kernels') |
| mock_sample.side_effect = [0.1] |
| mock_randint.side_effect = [1, 1] |
| (i, j) = rci.sample_offset(img_gt, (5, 5)) |
| assert i == 1 |
| assert j == 1 |
|
|
| |
|
|
| img = img_gt |
| offset = [0, 0] |
| target = [6, 6] |
| crop = rci.crop_img(img, offset, target) |
| assert np.allclose(img, crop[0]) |
| assert np.allclose(crop[1], [0, 0, 5, 5]) |
|
|
| target = [3, 2] |
| crop = rci.crop_img(img, offset, target) |
| assert np.allclose(np.array([[0, 0], [0, 0], [0, 0]]), crop[0]) |
| assert np.allclose(crop[1], [0, 0, 2, 3]) |
|
|
| |
| canvas_box = np.array([2, 3, 5, 5]) |
| bboxes = np.array([[2, 3, 4, 4], [0, 0, 1, 1], [1, 2, 4, 4], |
| [0, 0, 10, 10]]) |
| kept_bboxes, kept_idx = rci.crop_bboxes(bboxes, canvas_box) |
| assert np.allclose(kept_bboxes, |
| np.array([[0, 0, 2, 1], [0, 0, 2, 1], [0, 0, 3, 2]])) |
| assert kept_idx == [0, 2, 3] |
|
|
| bboxes = np.array([[10, 10, 11, 11], [0, 0, 1, 1]]) |
| kept_bboxes, kept_idx = rci.crop_bboxes(bboxes, canvas_box) |
| assert kept_bboxes.size == 0 |
| assert kept_bboxes.shape == (0, 4) |
| assert len(kept_idx) == 0 |
|
|
| |
| rci = transforms.RandomCropInstances(3, instance_key='gt_kernels') |
| results = {} |
| gt_kernels = [img_gt, img_gt.copy()] |
| results['gt_kernels'] = BitmapMasks(gt_kernels, 5, 5) |
| results['img'] = img_gt.copy() |
| results['mask_fields'] = ['gt_kernels'] |
| mock_sample.side_effect = [0.1] |
| mock_randint.side_effect = [1, 1] |
| output = rci(results) |
| target = np.array([[0, 0, 0], [0, 1, 1], [0, 1, 1]]) |
| assert output['img_shape'] == (3, 3) |
|
|
| assert np.allclose(output['img'], target) |
|
|
| assert np.allclose(output['gt_kernels'].masks[0], target) |
| assert np.allclose(output['gt_kernels'].masks[1], target) |
|
|
|
|
| @mock.patch('%s.transforms.np.random.random_sample' % __name__) |
| def test_scale_aspect_jitter(mock_random): |
| img_scale = [(3000, 1000)] |
| ratio_range = (0.5, 1.5) |
| aspect_ratio_range = (1, 1) |
| multiscale_mode = 'value' |
| long_size_bound = 2000 |
| short_size_bound = 640 |
| resize_type = 'long_short_bound' |
| keep_ratio = False |
| jitter = transforms.ScaleAspectJitter( |
| img_scale=img_scale, |
| ratio_range=ratio_range, |
| aspect_ratio_range=aspect_ratio_range, |
| multiscale_mode=multiscale_mode, |
| long_size_bound=long_size_bound, |
| short_size_bound=short_size_bound, |
| resize_type=resize_type, |
| keep_ratio=keep_ratio) |
| mock_random.side_effect = [0.5] |
|
|
| |
|
|
| result = jitter.sample_from_range([100, 200]) |
| assert result == 150 |
|
|
| |
| results = {} |
| results['img'] = np.zeros((4000, 1000)) |
| mock_random.side_effect = [0.5, 1] |
| jitter._random_scale(results) |
| |
| |
| assert results['scale'] == (650, 2600) |
|
|
|
|
| @mock.patch('%s.transforms.np.random.random_sample' % __name__) |
| def test_random_rotate(mock_random): |
|
|
| mock_random.side_effect = [0.5, 0] |
| results = {} |
| img = np.random.rand(5, 5) |
| results['img'] = img.copy() |
| results['mask_fields'] = ['masks'] |
| gt_kernels = [results['img'].copy()] |
| results['masks'] = BitmapMasks(gt_kernels, 5, 5) |
|
|
| rotater = transforms.RandomRotateTextDet() |
|
|
| results = rotater(results) |
| assert np.allclose(results['img'], img) |
| assert np.allclose(results['masks'].masks, img) |
|
|
|
|
| def test_color_jitter(): |
| img = np.ones((64, 256, 3), dtype=np.uint8) |
| results = {'img': img} |
|
|
| pt_official_color_jitter = TF.ColorJitter() |
| output1 = pt_official_color_jitter(img) |
|
|
| color_jitter = transforms.ColorJitter() |
| output2 = color_jitter(results) |
|
|
| assert np.allclose(output1, output2['img']) |
|
|
|
|
| def test_affine_jitter(): |
| img = np.ones((64, 256, 3), dtype=np.uint8) |
| results = {'img': img} |
|
|
| pt_official_affine_jitter = TF.RandomAffine(degrees=0) |
| output1 = pt_official_affine_jitter(Image.fromarray(img)) |
|
|
| affine_jitter = transforms.AffineJitter( |
| degrees=0, |
| translate=None, |
| scale=None, |
| shear=None, |
| resample=False, |
| fillcolor=0) |
| output2 = affine_jitter(results) |
|
|
| assert np.allclose(np.array(output1), output2['img']) |
|
|
|
|
| def test_random_scale(): |
| h, w, c = 100, 100, 3 |
| img = np.ones((h, w, c), dtype=np.uint8) |
| results = {'img': img, 'img_shape': (h, w, c)} |
|
|
| polygon = np.array([0., 0., 0., 10., 10., 10., 10., 0.]) |
|
|
| results['gt_masks'] = PolygonMasks([[polygon]], *(img.shape[:2])) |
| results['mask_fields'] = ['gt_masks'] |
|
|
| size = 100 |
| scale = (2., 2.) |
| random_scaler = transforms.RandomScaling(size=size, scale=scale) |
|
|
| results = random_scaler(results) |
|
|
| out_img = results['img'] |
| out_poly = results['gt_masks'].masks[0][0] |
| gt_poly = polygon * 2 |
|
|
| assert np.allclose(out_img.shape, (2 * h, 2 * w, c)) |
| assert np.allclose(out_poly, gt_poly) |
|
|
|
|
| @mock.patch('%s.transforms.np.random.randint' % __name__) |
| def test_random_crop_flip(mock_randint): |
| img = np.ones((10, 10, 3), dtype=np.uint8) |
| img[0, 0, :] = 0 |
| results = {'img': img, 'img_shape': img.shape} |
|
|
| polygon = np.array([0., 0., 0., 10., 10., 10., 10., 0.]) |
|
|
| results['gt_masks'] = PolygonMasks([[polygon]], *(img.shape[:2])) |
| results['gt_masks_ignore'] = PolygonMasks([], *(img.shape[:2])) |
| results['mask_fields'] = ['gt_masks', 'gt_masks_ignore'] |
|
|
| crop_ratio = 1.1 |
| iter_num = 3 |
| random_crop_fliper = transforms.RandomCropFlip( |
| crop_ratio=crop_ratio, iter_num=iter_num) |
|
|
| |
| pad_ratio = 0.1 |
| h, w = img.shape[:2] |
| pad_h = int(h * pad_ratio) |
| pad_w = int(w * pad_ratio) |
| all_polys = results['gt_masks'].masks |
| h_axis, w_axis = random_crop_fliper.generate_crop_target( |
| img, all_polys, pad_h, pad_w) |
|
|
| assert np.allclose(h_axis, (0, 11)) |
| assert np.allclose(w_axis, (0, 11)) |
|
|
| |
| polygon = np.array([1., 1., 1., 9., 9., 9., 9., 1.]) |
| results['gt_masks'] = PolygonMasks([[polygon]], *(img.shape[:2])) |
| results['gt_masks_ignore'] = PolygonMasks([[polygon]], *(img.shape[:2])) |
|
|
| mock_randint.side_effect = [0, 1, 2] |
| results = random_crop_fliper(results) |
|
|
| out_img = results['img'] |
| out_poly = results['gt_masks'].masks[0][0] |
| gt_img = img |
| gt_poly = polygon |
|
|
| assert np.allclose(out_img, gt_img) |
| assert np.allclose(out_poly, gt_poly) |
|
|
|
|
| @mock.patch('%s.transforms.np.random.random_sample' % __name__) |
| @mock.patch('%s.transforms.np.random.randint' % __name__) |
| def test_random_crop_poly_instances(mock_randint, mock_sample): |
| results = {} |
| img = np.zeros((30, 30, 3)) |
| poly_masks = PolygonMasks([[ |
| np.array([5., 5., 25., 5., 25., 10., 5., 10.]) |
| ], [np.array([5., 20., 25., 20., 25., 25., 5., 25.])]], 30, 30) |
| results['img'] = img |
| results['gt_masks'] = poly_masks |
| results['gt_masks_ignore'] = PolygonMasks([], 30, 30) |
| results['mask_fields'] = ['gt_masks', 'gt_masks_ignore'] |
| results['gt_labels'] = [1, 1] |
| rcpi = transforms.RandomCropPolyInstances( |
| instance_key='gt_masks', crop_ratio=1.0, min_side_ratio=0.3) |
|
|
| |
| mock_randint.side_effect = [0, 0, 0, 0, 30, 0, 0, 0, 15] |
| crop_box = rcpi.sample_crop_box((30, 30), results) |
| assert np.allclose(np.array(crop_box), np.array([0, 0, 30, 15])) |
|
|
| |
| mock_randint.side_effect = [0, 0, 0, 0, 30, 0, 15, 0, 30] |
| mock_sample.side_effect = [0.1] |
| output = rcpi(results) |
| target = np.array([5., 5., 25., 5., 25., 10., 5., 10.]) |
| assert len(output['gt_masks']) == 1 |
| assert len(output['gt_masks_ignore']) == 0 |
| assert np.allclose(output['gt_masks'].masks[0][0], target) |
| assert output['img'].shape == (15, 30, 3) |
|
|
| |
| mock_randint.side_effect = [0, 0, 0, 0, 30, 0, 15, 0, 30] |
| mock_sample.side_effect = [0.1] |
| rcpi = transforms.RandomCropPolyInstances( |
| instance_key='gt_masks_ignore', crop_ratio=1.0, min_side_ratio=0.3) |
| results['img'] = img |
| results['gt_masks'] = poly_masks |
| output = rcpi(results) |
| assert len(output['gt_masks']) == 2 |
| assert np.allclose(output['gt_masks'].masks[0][0], poly_masks.masks[0][0]) |
| assert np.allclose(output['gt_masks'].masks[1][0], poly_masks.masks[1][0]) |
| assert output['img'].shape == (30, 30, 3) |
|
|
|
|
| @mock.patch('%s.transforms.np.random.random_sample' % __name__) |
| def test_random_rotate_poly_instances(mock_sample): |
| results = {} |
| img = np.zeros((30, 30, 3)) |
| poly_masks = PolygonMasks( |
| [[np.array([10., 10., 20., 10., 20., 20., 10., 20.])]], 30, 30) |
| results['img'] = img |
| results['gt_masks'] = poly_masks |
| results['mask_fields'] = ['gt_masks'] |
| rrpi = transforms.RandomRotatePolyInstances(rotate_ratio=1.0, max_angle=90) |
|
|
| mock_sample.side_effect = [0., 1.] |
| output = rrpi(results) |
| assert np.allclose(output['gt_masks'].masks[0][0], |
| np.array([10., 20., 10., 10., 20., 10., 20., 20.])) |
| assert output['img'].shape == (30, 30, 3) |
|
|
|
|
| @mock.patch('%s.transforms.np.random.random_sample' % __name__) |
| def test_square_resize_pad(mock_sample): |
| results = {} |
| img = np.zeros((15, 30, 3)) |
| polygon = np.array([10., 5., 20., 5., 20., 10., 10., 10.]) |
| poly_masks = PolygonMasks([[polygon]], 15, 30) |
| results['img'] = img |
| results['gt_masks'] = poly_masks |
| results['mask_fields'] = ['gt_masks'] |
| srp = transforms.SquareResizePad(target_size=40, pad_ratio=0.5) |
|
|
| |
| mock_sample.side_effect = [0.] |
| output = srp(results) |
| target = 4. / 3 * polygon |
| target[1::2] += 10. |
| assert np.allclose(output['gt_masks'].masks[0][0], target) |
| assert output['img'].shape == (40, 40, 3) |
|
|
| |
| results['img'] = img |
| results['gt_masks'] = poly_masks |
| mock_sample.side_effect = [1.] |
| output = srp(results) |
| target = polygon.copy() |
| target[::2] *= 4. / 3 |
| target[1::2] *= 8. / 3 |
| assert np.allclose(output['gt_masks'].masks[0][0], target) |
| assert output['img'].shape == (40, 40, 3) |
|
|
|
|
| def test_pyramid_rescale(): |
| img = np.random.randint(0, 256, size=(128, 100, 3), dtype=np.uint8) |
| x = {'img': copy.deepcopy(img)} |
| f = transforms.PyramidRescale() |
| results = f(x) |
| assert results['img'].shape == (128, 100, 3) |
|
|
| |
| with pytest.raises(AssertionError): |
| transforms.PyramidRescale(base_shape=(128)) |
| with pytest.raises(AssertionError): |
| transforms.PyramidRescale(base_shape=128) |
| with pytest.raises(AssertionError): |
| transforms.PyramidRescale(factor=[]) |
| with pytest.raises(AssertionError): |
| transforms.PyramidRescale(randomize_factor=[]) |
| with pytest.raises(AssertionError): |
| f({}) |
|
|
| |
| f_derandomized = transforms.PyramidRescale( |
| factor=0, randomize_factor=False) |
| results = f_derandomized({'img': copy.deepcopy(img)}) |
| assert np.all(results['img'] == img) |
|
|