359 lines
13 KiB
Python
359 lines
13 KiB
Python
# Copyright (c) OpenMMLab. All rights reserved.
|
|
import copy
|
|
from unittest import TestCase
|
|
from unittest.mock import patch
|
|
|
|
import numpy as np
|
|
|
|
import mmcls.datasets # noqa: F401,F403
|
|
from mmcls.registry import TRANSFORMS
|
|
|
|
|
|
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 RandomResizedCrop(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 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 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 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)')
|