mmpretrain/tests/test_datasets/test_transforms/test_processing.py

867 lines
32 KiB
Python

# Copyright (c) OpenMMLab. All rights reserved.
import copy
import math
import random
from unittest import TestCase
from unittest.mock import ANY, call, patch
import mmengine
import numpy as np
import pytest
from mmpretrain.registry import TRANSFORMS
try:
import albumentations
except ImportError:
albumentations = None
def construct_toy_data():
img = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]],
dtype=np.uint8)
img = np.stack([img, img, img], axis=-1)
results = dict()
# image
results['ori_img'] = img
results['img'] = copy.deepcopy(img)
results['ori_shape'] = img.shape
results['img_shape'] = img.shape
return results
class TestRandomCrop(TestCase):
def test_assertion(self):
with self.assertRaises(AssertionError):
cfg = dict(type='RandomCrop', crop_size=-1)
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(type='RandomCrop', crop_size=(1, 2, 3))
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(type='RandomCrop', crop_size=(1, -2))
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(type='RandomCrop', crop_size=224, padding_mode='co')
TRANSFORMS.build(cfg)
def test_transform(self):
results = dict(img=np.random.randint(0, 256, (256, 256, 3), np.uint8))
# test random crop by default.
cfg = dict(type='RandomCrop', crop_size=224)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test int padding and int pad_val.
cfg = dict(
type='RandomCrop', crop_size=(224, 224), padding=2, pad_val=1)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test int padding and sequence pad_val.
cfg = dict(
type='RandomCrop', crop_size=224, padding=2, pad_val=(0, 50, 0))
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test sequence padding.
cfg = dict(type='RandomCrop', crop_size=224, padding=(2, 3, 4, 5))
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test pad_if_needed.
cfg = dict(
type='RandomCrop',
crop_size=300,
pad_if_needed=True,
padding_mode='edge')
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (300, 300, 3))
# test large crop size.
results = dict(img=np.random.randint(0, 256, (256, 256, 3), np.uint8))
cfg = dict(type='RandomCrop', crop_size=300)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (256, 256, 3))
# test equal size.
results = dict(img=np.random.randint(0, 256, (256, 256, 3), np.uint8))
cfg = dict(type='RandomCrop', crop_size=256)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (256, 256, 3))
def test_repr(self):
cfg = dict(type='RandomCrop', crop_size=224)
transform = TRANSFORMS.build(cfg)
self.assertEqual(
repr(transform), 'RandomCrop(crop_size=(224, 224), padding=None, '
'pad_if_needed=False, pad_val=0, padding_mode=constant)')
class TestRandomResizedCrop(TestCase):
def test_assertion(self):
with self.assertRaises(AssertionError):
cfg = dict(type='RandomResizedCrop', scale=-1)
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(type='RandomResizedCrop', scale=(1, 2, 3))
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(type='RandomResizedCrop', scale=(1, -2))
TRANSFORMS.build(cfg)
with self.assertRaises(ValueError):
cfg = dict(
type='RandomResizedCrop', scale=224, crop_ratio_range=(1, 0.1))
TRANSFORMS.build(cfg)
with self.assertRaises(ValueError):
cfg = dict(
type='RandomResizedCrop',
scale=224,
aspect_ratio_range=(1, 0.1))
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(type='RandomResizedCrop', scale=224, max_attempts=-1)
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(type='RandomResizedCrop', scale=224, interpolation='ne')
TRANSFORMS.build(cfg)
def test_transform(self):
results = dict(img=np.random.randint(0, 256, (256, 256, 3), np.uint8))
# test random crop by default.
cfg = dict(type='RandomResizedCrop', scale=224)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test crop_ratio_range.
cfg = dict(
type='RandomResizedCrop',
scale=(224, 224),
crop_ratio_range=(0.5, 0.8))
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test aspect_ratio_range.
cfg = dict(
type='RandomResizedCrop', scale=224, aspect_ratio_range=(0.5, 0.8))
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test max_attempts.
cfg = dict(type='RandomResizedCrop', scale=224, max_attempts=0)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test fall back with extreme low in_ratio
results = dict(img=np.random.randint(0, 256, (10, 256, 3), np.uint8))
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test fall back with extreme low in_ratio
results = dict(img=np.random.randint(0, 256, (256, 10, 3), np.uint8))
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test large crop size.
results = dict(img=np.random.randint(0, 256, (256, 256, 3), np.uint8))
cfg = dict(type='RandomResizedCrop', scale=300)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (300, 300, 3))
def test_repr(self):
cfg = dict(type='RandomResizedCrop', scale=224)
transform = TRANSFORMS.build(cfg)
self.assertEqual(
repr(transform), 'RandomResizedCrop(scale=(224, 224), '
'crop_ratio_range=(0.08, 1.0), aspect_ratio_range=(0.75, 1.3333), '
'max_attempts=10, interpolation=bilinear, backend=cv2)')
class TestEfficientNetRandomCrop(TestCase):
def test_assertion(self):
with self.assertRaises(AssertionError):
cfg = dict(type='EfficientNetRandomCrop', scale=(1, 1))
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(
type='EfficientNetRandomCrop', scale=224, min_covered=-1)
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(
type='EfficientNetRandomCrop', scale=224, crop_padding=-1)
TRANSFORMS.build(cfg)
def test_transform(self):
results = dict(img=np.random.randint(0, 256, (256, 256, 3), np.uint8))
# test random crop by default.
cfg = dict(type='EfficientNetRandomCrop', scale=224)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test crop_ratio_range.
cfg = dict(
type='EfficientNetRandomCrop',
scale=224,
crop_ratio_range=(0.5, 0.8))
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test aspect_ratio_range.
cfg = dict(
type='EfficientNetRandomCrop',
scale=224,
aspect_ratio_range=(0.5, 0.8))
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test max_attempts.
cfg = dict(type='EfficientNetRandomCrop', scale=224, max_attempts=0)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test min_covered.
cfg = dict(type='EfficientNetRandomCrop', scale=224, min_covered=.9)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test crop_padding.
cfg = dict(
type='EfficientNetRandomCrop',
scale=224,
min_covered=0.9,
crop_padding=10)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test large crop size.
results = dict(img=np.random.randint(0, 256, (256, 256, 3), np.uint8))
cfg = dict(type='EfficientNetRandomCrop', scale=300)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (300, 300, 3))
def test_repr(self):
cfg = dict(type='EfficientNetRandomCrop', scale=224)
transform = TRANSFORMS.build(cfg)
self.assertEqual(
repr(transform), 'EfficientNetRandomCrop(scale=(224, 224), '
'crop_ratio_range=(0.08, 1.0), aspect_ratio_range=(0.75, 1.3333), '
'max_attempts=10, interpolation=bicubic, backend=cv2, '
'min_covered=0.1, crop_padding=32)')
class TestResizeEdge(TestCase):
def test_transform(self):
results = dict(img=np.random.randint(0, 256, (128, 256, 3), np.uint8))
# test resize short edge by default.
cfg = dict(type='ResizeEdge', scale=224)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 448, 3))
# test resize long edge.
cfg = dict(type='ResizeEdge', scale=224, edge='long')
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (112, 224, 3))
# test resize width.
cfg = dict(type='ResizeEdge', scale=224, edge='width')
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (112, 224, 3))
# test resize height.
cfg = dict(type='ResizeEdge', scale=224, edge='height')
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 448, 3))
# test invalid edge
with self.assertRaisesRegex(AssertionError, 'Invalid edge "hi"'):
cfg = dict(type='ResizeEdge', scale=224, edge='hi')
TRANSFORMS.build(cfg)
def test_repr(self):
cfg = dict(type='ResizeEdge', scale=224, edge='height')
transform = TRANSFORMS.build(cfg)
self.assertEqual(
repr(transform), 'ResizeEdge(scale=224, edge=height, backend=cv2, '
'interpolation=bilinear)')
class TestEfficientNetCenterCrop(TestCase):
def test_assertion(self):
with self.assertRaises(AssertionError):
cfg = dict(type='EfficientNetCenterCrop', crop_size=(1, 1))
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(type='EfficientNetCenterCrop', crop_size=-1)
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(
type='EfficientNetCenterCrop', crop_size=224, crop_padding=-1)
TRANSFORMS.build(cfg)
def test_transform(self):
results = dict(img=np.random.randint(0, 256, (256, 256, 3), np.uint8))
# test random crop by default.
cfg = dict(type='EfficientNetCenterCrop', crop_size=224)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test crop_padding.
cfg = dict(
type='EfficientNetCenterCrop', crop_size=224, crop_padding=10)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (224, 224, 3))
# test large crop size.
results = dict(img=np.random.randint(0, 256, (256, 256, 3), np.uint8))
cfg = dict(type='EfficientNetCenterCrop', crop_size=300)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertTupleEqual(results['img'].shape, (300, 300, 3))
def test_repr(self):
cfg = dict(type='EfficientNetCenterCrop', crop_size=224)
transform = TRANSFORMS.build(cfg)
self.assertEqual(
repr(transform), 'EfficientNetCenterCrop(crop_size=224, '
'crop_padding=32, interpolation=bicubic, backend=cv2)')
class TestRandomErasing(TestCase):
def test_initialize(self):
# test erase_prob assertion
with self.assertRaises(AssertionError):
cfg = dict(type='RandomErasing', erase_prob=-1.)
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(type='RandomErasing', erase_prob=1)
TRANSFORMS.build(cfg)
# test area_ratio assertion
with self.assertRaises(AssertionError):
cfg = dict(type='RandomErasing', min_area_ratio=-1.)
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(type='RandomErasing', max_area_ratio=1)
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
# min_area_ratio should be smaller than max_area_ratio
cfg = dict(
type='RandomErasing', min_area_ratio=0.6, max_area_ratio=0.4)
TRANSFORMS.build(cfg)
# test aspect_range assertion
with self.assertRaises(AssertionError):
cfg = dict(type='RandomErasing', aspect_range='str')
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = dict(type='RandomErasing', aspect_range=-1)
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
# In aspect_range (min, max), min should be smaller than max.
cfg = dict(type='RandomErasing', aspect_range=[1.6, 0.6])
TRANSFORMS.build(cfg)
# test mode assertion
with self.assertRaises(AssertionError):
cfg = dict(type='RandomErasing', mode='unknown')
TRANSFORMS.build(cfg)
# test fill_std assertion
with self.assertRaises(AssertionError):
cfg = dict(type='RandomErasing', fill_std='unknown')
TRANSFORMS.build(cfg)
# test implicit conversion of aspect_range
cfg = dict(type='RandomErasing', aspect_range=0.5)
random_erasing = TRANSFORMS.build(cfg)
assert random_erasing.aspect_range == (0.5, 2.)
cfg = dict(type='RandomErasing', aspect_range=2.)
random_erasing = TRANSFORMS.build(cfg)
assert random_erasing.aspect_range == (0.5, 2.)
# test implicit conversion of fill_color
cfg = dict(type='RandomErasing', fill_color=15)
random_erasing = TRANSFORMS.build(cfg)
assert random_erasing.fill_color == [15, 15, 15]
# test implicit conversion of fill_std
cfg = dict(type='RandomErasing', fill_std=0.5)
random_erasing = TRANSFORMS.build(cfg)
assert random_erasing.fill_std == [0.5, 0.5, 0.5]
def test_transform(self):
# test when erase_prob=0.
results = construct_toy_data()
cfg = dict(
type='RandomErasing',
erase_prob=0.,
mode='const',
fill_color=(255, 255, 255))
random_erasing = TRANSFORMS.build(cfg)
results = random_erasing(results)
np.testing.assert_array_equal(results['img'], results['ori_img'])
# test mode 'const'
results = construct_toy_data()
cfg = dict(
type='RandomErasing',
erase_prob=1.,
mode='const',
fill_color=(255, 255, 255))
with patch('numpy.random', np.random.RandomState(0)):
random_erasing = TRANSFORMS.build(cfg)
results = random_erasing(results)
expect_out = np.array(
[[1, 255, 3, 4], [5, 255, 7, 8], [9, 10, 11, 12]],
dtype=np.uint8)
expect_out = np.stack([expect_out] * 3, axis=-1)
np.testing.assert_array_equal(results['img'], expect_out)
# test mode 'rand' with normal distribution
results = construct_toy_data()
cfg = dict(type='RandomErasing', erase_prob=1., mode='rand')
with patch('numpy.random', np.random.RandomState(0)):
random_erasing = TRANSFORMS.build(cfg)
results = random_erasing(results)
expect_out = results['ori_img']
expect_out[:2, 1] = [[159, 98, 76], [14, 69, 122]]
np.testing.assert_array_equal(results['img'], expect_out)
# test mode 'rand' with uniform distribution
results = construct_toy_data()
cfg = dict(
type='RandomErasing',
erase_prob=1.,
mode='rand',
fill_std=(10, 255, 0))
with patch('numpy.random', np.random.RandomState(0)):
random_erasing = TRANSFORMS.build(cfg)
results = random_erasing(results)
expect_out = results['ori_img']
expect_out[:2, 1] = [[113, 255, 128], [126, 83, 128]]
np.testing.assert_array_equal(results['img'], expect_out)
def test_repr(self):
cfg = dict(
type='RandomErasing',
erase_prob=0.5,
mode='const',
aspect_range=(0.3, 1.3),
fill_color=(255, 255, 255))
transform = TRANSFORMS.build(cfg)
self.assertEqual(
repr(transform),
'RandomErasing(erase_prob=0.5, min_area_ratio=0.02, '
'max_area_ratio=0.4, aspect_range=(0.3, 1.3), mode=const, '
'fill_color=(255, 255, 255), fill_std=None)')
class TestColorJitter(TestCase):
DEFAULT_ARGS = dict(
type='ColorJitter',
brightness=0.5,
contrast=0.5,
saturation=0.5,
hue=0.2)
def test_initialize(self):
cfg = dict(
type='ColorJitter',
brightness=(0.8, 1.2),
contrast=[0.5, 1.5],
saturation=0.,
hue=0.2)
transform = TRANSFORMS.build(cfg)
self.assertEqual(transform.brightness, (0.8, 1.2))
self.assertEqual(transform.contrast, (0.5, 1.5))
self.assertIsNone(transform.saturation)
self.assertEqual(transform.hue, (-0.2, 0.2))
with self.assertRaisesRegex(ValueError, 'If hue is a single number'):
cfg = {**self.DEFAULT_ARGS, 'hue': -0.2}
TRANSFORMS.build(cfg)
with self.assertRaisesRegex(TypeError, 'hue should be a single'):
cfg = {**self.DEFAULT_ARGS, 'hue': [0.5, 0.4, 0.2]}
TRANSFORMS.build(cfg)
logger = mmengine.MMLogger.get_current_instance()
with self.assertLogs(logger, 'WARN') as log:
cfg = {**self.DEFAULT_ARGS, 'hue': [-1, 0.4]}
transform = TRANSFORMS.build(cfg)
self.assertIn('ColorJitter hue values', log.output[0])
self.assertEqual(transform.hue, (-0.5, 0.4))
def test_transform(self):
ori_img = np.random.randint(0, 256, (256, 256, 3), np.uint8)
results = dict(img=copy.deepcopy(ori_img))
# test transform
cfg = copy.deepcopy(self.DEFAULT_ARGS)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertEqual(results['img'].dtype, ori_img.dtype)
assert not np.equal(results['img'], ori_img).all()
# test call with brightness, contrast and saturation are all 0
results = dict(img=copy.deepcopy(ori_img))
cfg = dict(
type='ColorJitter', brightness=0., contrast=0., saturation=0.)
transform = TRANSFORMS.build(cfg)
results = transform(results)
self.assertEqual(results['img'].dtype, ori_img.dtype)
assert np.equal(results['img'], ori_img).all()
# test call index
cfg = {**self.DEFAULT_ARGS, 'contrast': 0.}
transform = TRANSFORMS.build(cfg)
with patch('numpy.random', np.random.RandomState(0)):
mmcv_module = 'mmpretrain.datasets.transforms.processing.mmcv'
call_list = [
call.adjust_color(ANY, alpha=ANY, backend='pillow'),
call.adjust_hue(ANY, ANY, backend='pillow'),
call.adjust_brightness(ANY, ANY, backend='pillow'),
]
with patch(mmcv_module, autospec=True) as mock:
transform(results)
self.assertEqual(mock.mock_calls, call_list)
def test_repr(self):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
transform = TRANSFORMS.build(cfg)
self.assertEqual(
repr(transform), 'ColorJitter(brightness=(0.5, 1.5), '
'contrast=(0.5, 1.5), saturation=(0.5, 1.5), hue=(-0.2, 0.2))')
class TestLighting(TestCase):
def setUp(self):
EIGVAL = [0.2175, 0.0188, 0.0045]
EIGVEC = [
[-0.5836, -0.6948, 0.4203],
[-0.5808, -0.0045, -0.814],
[-0.5675, 0.7192, 0.4009],
]
self.DEFAULT_ARGS = dict(
type='Lighting',
eigval=EIGVAL,
eigvec=EIGVEC,
alphastd=25.5,
to_rgb=False)
def test_assertion(self):
with self.assertRaises(AssertionError):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['eigval'] = -1
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['eigvec'] = None
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['alphastd'] = 'Lighting'
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['eigvec'] = dict()
TRANSFORMS.build(cfg)
with self.assertRaises(AssertionError):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['eigvec'] = [
[-0.5836, -0.6948, 0.4203],
[-0.5808, -0.0045, -0.814],
[-0.5675, 0.7192, 0.4009, 0.10],
]
TRANSFORMS.build(cfg)
def test_transform(self):
ori_img = np.ones((256, 256, 3), np.uint8) * 127
results = dict(img=copy.deepcopy(ori_img))
# Test transform with non-img-keyword result
with self.assertRaises(AssertionError):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
lightening_module = TRANSFORMS.build(cfg)
empty_results = dict()
lightening_module(empty_results)
# test call
cfg = copy.deepcopy(self.DEFAULT_ARGS)
lightening_module = TRANSFORMS.build(cfg)
with patch('numpy.random', np.random.RandomState(0)):
results = lightening_module(results)
self.assertEqual(results['img'].dtype, ori_img.dtype)
assert not np.equal(results['img'], ori_img).all()
# test call with alphastd == 0
results = dict(img=copy.deepcopy(ori_img))
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['alphastd'] = 0.0
lightening_module = TRANSFORMS.build(cfg)
results = lightening_module(results)
self.assertEqual(results['img'].dtype, ori_img.dtype)
assert np.equal(results['img'], ori_img).all()
def test_repr(self):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
transform = TRANSFORMS.build(cfg)
self.assertEqual(
repr(transform), 'Lighting(eigval=[0.2175, 0.0188, 0.0045], eigvec'
'=[[-0.5836, -0.6948, 0.4203], [-0.5808, -0.0045, -0.814], ['
'-0.5675, 0.7192, 0.4009]], alphastd=25.5, to_rgb=False)')
class TestAlbumentations(TestCase):
DEFAULT_ARGS = dict(
type='Albumentations', transforms=[dict(type='ChannelShuffle', p=1)])
@pytest.mark.skipif(
albumentations is None, reason='No Albumentations module.')
def test_assertion(self):
# Test with non-list transforms
with self.assertRaises(AssertionError):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['transforms'] = 1
TRANSFORMS.build(cfg)
# Test with non-dict transforms item.
with self.assertRaises(AssertionError):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['transforms'] = [dict(p=1)]
TRANSFORMS.build(cfg)
# Test with dict transforms item without keyword 'type'.
with self.assertRaises(AssertionError):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['transforms'] = [[]]
TRANSFORMS.build(cfg)
# Test with dict transforms item with wrong type.
with self.assertRaises(TypeError):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['transforms'] = [dict(type=[])]
TRANSFORMS.build(cfg)
# Test with dict transforms item with wrong type.
with self.assertRaises(AssertionError):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['keymap'] = []
TRANSFORMS.build(cfg)
@pytest.mark.skipif(
albumentations is None, reason='No Albumentations module.')
def test_transform(self):
ori_img = np.random.randint(0, 256, (256, 256, 3), np.uint8)
results = dict(img=copy.deepcopy(ori_img))
# Test transform with non-img-keyword result
with self.assertRaises(AssertionError):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
albu_module = TRANSFORMS.build(cfg)
empty_results = dict()
albu_module(empty_results)
# Test normal case
results = dict(img=copy.deepcopy(ori_img))
cfg = copy.deepcopy(self.DEFAULT_ARGS)
albu_module = TRANSFORMS.build(cfg)
ablu_result = albu_module(results)
# Test using 'Albu'
results = dict(img=copy.deepcopy(ori_img))
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['type'] = 'Albu'
albu_module = TRANSFORMS.build(cfg)
ablu_result = albu_module(results)
# Test with keymap
results = dict(img=copy.deepcopy(ori_img))
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['keymap'] = dict(img='image')
albu_module = TRANSFORMS.build(cfg)
ablu_result = albu_module(results)
# Test with nested transform
results = dict(img=copy.deepcopy(ori_img))
cfg = copy.deepcopy(self.DEFAULT_ARGS)
nested_transform_cfg = [
dict(
type='ShiftScaleRotate',
shift_limit=0.0625,
scale_limit=0.0,
rotate_limit=0,
interpolation=1,
p=0.5),
dict(
type='RandomBrightnessContrast',
brightness_limit=[0.1, 0.3],
contrast_limit=[0.1, 0.3],
p=0.2),
dict(type='ChannelShuffle', p=0.1),
dict(
type='OneOf',
transforms=[
dict(type='Blur', blur_limit=3, p=1.0),
dict(type='MedianBlur', blur_limit=3, p=1.0)
],
p=0.1),
]
cfg['transforms'] = nested_transform_cfg
mmpretrain_module = TRANSFORMS.build(cfg)
mmpretrain_module(results)
# test to be same with albumentations 3rd package
np.random.seed(0)
random.seed(0)
import albumentations as A
ablu_transform_3rd = A.Compose([
A.RandomCrop(width=256, height=256),
A.HorizontalFlip(p=0.5),
A.RandomBrightnessContrast(p=0.2),
])
transformed_image_3rd = ablu_transform_3rd(
image=copy.deepcopy(ori_img))['image']
np.random.seed(0)
random.seed(0)
results = dict(img=copy.deepcopy(ori_img))
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['transforms'] = [
dict(type='RandomCrop', width=256, height=256),
dict(type='HorizontalFlip', p=0.5),
dict(type='RandomBrightnessContrast', p=0.2)
]
mmpretrain_module = TRANSFORMS.build(cfg)
transformed_image_mmpretrain = mmpretrain_module(results)['img']
assert np.equal(transformed_image_3rd,
transformed_image_mmpretrain).all()
# Test class obj case
results = dict(img=np.random.randint(0, 256, (200, 300, 3), np.uint8))
cfg = copy.deepcopy(self.DEFAULT_ARGS)
cfg['transforms'] = [
dict(type=albumentations.SmallestMaxSize, max_size=400, p=1)
]
albu_module = TRANSFORMS.build(cfg)
ablu_result = albu_module(results)
assert 'img' in ablu_result
assert min(ablu_result['img'].shape[:2]) == 400
assert ablu_result['img_shape'] == (400, 600)
@pytest.mark.skipif(
albumentations is None, reason='No Albumentations module.')
def test_repr(self):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
transform = TRANSFORMS.build(cfg)
self.assertEqual(
repr(transform), "Albumentations(transforms=[{'type': "
"'ChannelShuffle', 'p': 1}])")
class TestSimMIMMaskGenerator(TestCase):
DEFAULT_ARGS = dict(
type='SimMIMMaskGenerator',
input_size=192,
mask_patch_size=32,
model_patch_size=4,
mask_ratio=0.6)
def test_transform(self):
img = np.random.randint(0, 256, (3, 192, 192), np.uint8)
results = {'img': img}
module = TRANSFORMS.build(self.DEFAULT_ARGS)
results = module(results)
self.assertTupleEqual(results['img'].shape, (3, 192, 192))
self.assertTupleEqual(results['mask'].shape, (48, 48))
def test_repr(self):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
transform = TRANSFORMS.build(cfg)
self.assertEqual(
repr(transform), 'SimMIMMaskGenerator(input_size=192, '
'mask_patch_size=32, model_patch_size=4, mask_ratio=0.6)')
class TestBEiTMaskGenerator(TestCase):
DEFAULT_ARGS = dict(
type='BEiTMaskGenerator',
input_size=(14, 14),
num_masking_patches=75,
max_num_patches=None,
min_num_patches=16)
def test_transform(self):
module = TRANSFORMS.build(self.DEFAULT_ARGS)
results = module({})
self.assertTupleEqual(results['mask'].shape, (14, 14))
def test_repr(self):
cfg = copy.deepcopy(self.DEFAULT_ARGS)
transform = TRANSFORMS.build(cfg)
log_aspect_ratio = (math.log(0.3), math.log(1 / 0.3))
self.assertEqual(
repr(transform), 'BEiTMaskGenerator(height=14, width=14, '
'num_patches=196, num_masking_patches=75, min_num_patches=16, '
f'max_num_patches=75, log_aspect_ratio={log_aspect_ratio})')