867 lines
32 KiB
Python
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})')
|