mmcv/tests/test_transforms/test_transforms_processing.py

910 lines
37 KiB
Python

# Copyright (c) OpenMMLab. All rights reserved.
import copy
import os.path as osp
from unittest.mock import Mock
import numpy as np
import pytest
import mmcv
from mmcv.transforms import (TRANSFORMS, Normalize, Pad, RandomFlip,
RandomResize, Resize)
from mmcv.transforms.base import BaseTransform
try:
import torch
except ModuleNotFoundError:
torch = None
else:
import torchvision
from numpy.testing import assert_array_almost_equal, assert_array_equal
from PIL import Image
class TestNormalize:
def test_normalize(self):
img_norm_cfg = dict(
mean=[123.675, 116.28, 103.53],
std=[58.395, 57.12, 57.375],
to_rgb=True)
transform = Normalize(**img_norm_cfg)
results = dict()
img = mmcv.imread(
osp.join(osp.dirname(__file__), '../data/color.jpg'), 'color')
original_img = copy.deepcopy(img)
results['img'] = img
results = transform(results)
mean = np.array(img_norm_cfg['mean'])
std = np.array(img_norm_cfg['std'])
converted_img = (original_img[..., ::-1] - mean) / std
assert np.allclose(results['img'], converted_img)
def test_repr(self):
img_norm_cfg = dict(
mean=[123.675, 116.28, 103.53],
std=[58.395, 57.12, 57.375],
to_rgb=True)
transform = Normalize(**img_norm_cfg)
assert repr(transform) == ('Normalize(mean=[123.675 116.28 103.53 ], '
'std=[58.395 57.12 57.375], to_rgb=True)')
class TestResize:
def test_resize(self):
data_info = dict(
img=np.random.random((1333, 800, 3)),
gt_seg_map=np.random.random((1333, 800, 3)),
gt_bboxes=np.array([[0, 0, 112, 112]]),
gt_keypoints=np.array([[[20, 50, 1]]]))
with pytest.raises(AssertionError):
transform = Resize(scale=None, scale_factor=None)
with pytest.raises(TypeError):
transform = Resize(scale_factor=[])
# test scale is int
transform = Resize(scale=2000)
results = transform(copy.deepcopy(data_info))
assert results['img'].shape[:2] == (2000, 2000)
assert results['scale_factor'] == (2000 / 800, 2000 / 1333)
# test scale is tuple
transform = Resize(scale=(2000, 2000))
results = transform(copy.deepcopy(data_info))
assert results['img'].shape[:2] == (2000, 2000)
assert results['scale_factor'] == (2000 / 800, 2000 / 1333)
# test scale_factor is float
transform = Resize(scale_factor=2.0)
results = transform(copy.deepcopy(data_info))
assert results['img'].shape[:2] == (2666, 1600)
assert results['scale_factor'] == (2.0, 2.0)
# test scale_factor is tuple
transform = Resize(scale_factor=(1.5, 2))
results = transform(copy.deepcopy(data_info))
assert results['img'].shape[:2] == (2666, 1200)
assert results['scale_factor'] == (1.5, 2)
# test keep_ratio is True
transform = Resize(scale=(2000, 2000), keep_ratio=True)
results = transform(copy.deepcopy(data_info))
assert results['img'].shape[:2] == (2000, 1200)
assert results['scale'] == (1200, 2000)
assert results['scale_factor'] == (1200 / 800, 2000 / 1333)
# test resize_bboxes/seg/kps
transform = Resize(scale_factor=(1.5, 2))
results = transform(copy.deepcopy(data_info))
assert (results['gt_bboxes'] == np.array([[0, 0, 168, 224]])).all()
assert (results['gt_keypoints'] == np.array([[[30, 100, 1]]])).all()
assert results['gt_seg_map'].shape[:2] == (2666, 1200)
# test clip_object_border = False
data_info = dict(
img=np.random.random((300, 400, 3)),
gt_bboxes=np.array([[200, 150, 600, 450]]))
transform = Resize(scale=(200, 150), clip_object_border=False)
results = transform(data_info)
assert (results['gt_bboxes'] == np.array([100, 75, 300, 225])).all()
def test_repr(self):
transform = Resize(scale=(2000, 2000), keep_ratio=True)
assert repr(transform) == ('Resize(scale=(2000, 2000), '
'scale_factor=None, keep_ratio=True, '
'clip_object_border=True), backend=cv2), '
'interpolation=bilinear)')
class TestPad:
def test_pad(self):
# test size and size_divisor are both set
with pytest.raises(AssertionError):
Pad(size=(10, 10), size_divisor=2)
# test size and size_divisor are both None
with pytest.raises(AssertionError):
Pad(size=None, size_divisor=None)
# test size and pad_to_square are both None
with pytest.raises(AssertionError):
Pad(size=(10, 10), pad_to_square=True)
# test pad_val is not int or tuple
with pytest.raises(AssertionError):
Pad(size=(10, 10), pad_val=[])
# test padding_mode is not 'constant', 'edge', 'reflect' or 'symmetric'
with pytest.raises(AssertionError):
Pad(size=(10, 10), padding_mode='edg')
data_info = dict(
img=np.random.random((1333, 800, 3)),
gt_seg_map=np.random.random((1333, 800, 3)),
gt_bboxes=np.array([[0, 0, 112, 112]]),
gt_keypoints=np.array([[[20, 50, 1]]]))
# test pad img / gt_seg_map with size
trans = Pad(size=(1200, 2000))
results = trans(copy.deepcopy(data_info))
assert results['img'].shape[:2] == (2000, 1200)
assert results['gt_seg_map'].shape[:2] == (2000, 1200)
# test pad img/gt_seg_map with size_divisor
trans = Pad(size_divisor=11)
results = trans(copy.deepcopy(data_info))
assert results['img'].shape[:2] == (1342, 803)
assert results['gt_seg_map'].shape[:2] == (1342, 803)
# test pad img/gt_seg_map with pad_to_square
trans = Pad(pad_to_square=True)
results = trans(copy.deepcopy(data_info))
assert results['img'].shape[:2] == (1333, 1333)
assert results['gt_seg_map'].shape[:2] == (1333, 1333)
# test pad img/gt_seg_map with pad_to_square and size_divisor
trans = Pad(pad_to_square=True, size_divisor=11)
results = trans(copy.deepcopy(data_info))
assert results['img'].shape[:2] == (1342, 1342)
assert results['gt_seg_map'].shape[:2] == (1342, 1342)
# test pad img/gt_seg_map with pad_to_square and size_divisor
trans = Pad(pad_to_square=True, size_divisor=11)
results = trans(copy.deepcopy(data_info))
assert results['img'].shape[:2] == (1342, 1342)
assert results['gt_seg_map'].shape[:2] == (1342, 1342)
# test padding_mode
new_img = np.ones((1333, 800, 3))
data_info['img'] = new_img
trans = Pad(pad_to_square=True, padding_mode='edge')
results = trans(copy.deepcopy(data_info))
assert (results['img'] == np.ones((1333, 1333, 3))).all()
# test pad_val is dict
# test rgb image, size=(2000, 2000)
trans = Pad(
size=(2000, 2000),
pad_val=dict(img=(12, 12, 12), seg=(10, 10, 10)))
results = trans(copy.deepcopy(data_info))
assert (results['img'][1333:2000, 800:2000, :] == 12).all()
assert (results['gt_seg_map'][1333:2000, 800:2000, :] == 10).all()
trans = Pad(size=(2000, 2000), pad_val=dict(img=(12, 12, 12)))
results = trans(copy.deepcopy(data_info))
assert (results['img'][1333:2000, 800:2000, :] == 12).all()
assert (results['gt_seg_map'][1333:2000, 800:2000, :] == 255).all()
# test rgb image, pad_to_square=True
trans = Pad(
pad_to_square=True,
pad_val=dict(img=(12, 12, 12), seg=(10, 10, 10)))
results = trans(copy.deepcopy(data_info))
assert (results['img'][:, 800:1333, :] == 12).all()
assert (results['gt_seg_map'][:, 800:1333, :] == 10).all()
trans = Pad(pad_to_square=True, pad_val=dict(img=(12, 12, 12)))
results = trans(copy.deepcopy(data_info))
assert (results['img'][:, 800:1333, :] == 12).all()
assert (results['gt_seg_map'][:, 800:1333, :] == 255).all()
# test pad_val is int
# test rgb image
trans = Pad(size=(2000, 2000), pad_val=12)
results = trans(copy.deepcopy(data_info))
assert (results['img'][1333:2000, 800:2000, :] == 12).all()
assert (results['gt_seg_map'][1333:2000, 800:2000, :] == 255).all()
# test gray image
new_img = np.random.random((1333, 800))
data_info['img'] = new_img
new_semantic_seg = np.random.random((1333, 800))
data_info['gt_seg_map'] = new_semantic_seg
trans = Pad(size=(2000, 2000), pad_val=12)
results = trans(copy.deepcopy(data_info))
assert (results['img'][1333:2000, 800:2000] == 12).all()
assert (results['gt_seg_map'][1333:2000, 800:2000] == 255).all()
def test_repr(self):
trans = Pad(pad_to_square=True, size_divisor=11, padding_mode='edge')
assert repr(trans) == (
'Pad(size=None, size_divisor=11, pad_to_square=True, '
"pad_val={'img': 0, 'seg': 255}), padding_mode=edge)")
class TestCenterCrop:
@classmethod
def setup_class(cls):
img = mmcv.imread(
osp.join(osp.dirname(__file__), '../data/color.jpg'), 'color')
cls.original_img = copy.deepcopy(img)
seg = np.random.randint(0, 19, (300, 400)).astype(np.uint8)
cls.gt_semantic_map = copy.deepcopy(seg)
@staticmethod
def reset_results(results, original_img, gt_semantic_map):
results['img'] = copy.deepcopy(original_img)
results['gt_seg_map'] = copy.deepcopy(gt_semantic_map)
results['gt_bboxes'] = np.array([[0, 0, 210, 160],
[200, 150, 400, 300]])
results['gt_keypoints'] = np.array([[[20, 50, 1]], [[200, 150, 1]],
[[300, 225, 1]]])
return results
@pytest.mark.skipif(
condition=torch is None, reason='No torch in current env')
def test_error(self):
# test assertion if size is smaller than 0
with pytest.raises(AssertionError):
transform = dict(type='CenterCrop', crop_size=-1)
TRANSFORMS.build(transform)
# test assertion if size is tuple but one value is smaller than 0
with pytest.raises(AssertionError):
transform = dict(type='CenterCrop', crop_size=(224, -1))
TRANSFORMS.build(transform)
# test assertion if size is tuple and len(size) < 2
with pytest.raises(AssertionError):
transform = dict(type='CenterCrop', crop_size=(224, ))
TRANSFORMS.build(transform)
# test assertion if size is tuple len(size) > 2
with pytest.raises(AssertionError):
transform = dict(type='CenterCrop', crop_size=(224, 224, 3))
TRANSFORMS.build(transform)
def test_repr(self):
# test repr
transform = dict(type='CenterCrop', crop_size=224)
center_crop_module = TRANSFORMS.build(transform)
assert isinstance(repr(center_crop_module), str)
def test_transform(self):
results = {}
self.reset_results(results, self.original_img, self.gt_semantic_map)
# test CenterCrop when size is int
transform = dict(type='CenterCrop', crop_size=224)
center_crop_module = TRANSFORMS.build(transform)
results = center_crop_module(results)
assert results['height'] == 224
assert results['width'] == 224
assert (results['img'] == self.original_img[38:262, 88:312, ...]).all()
assert (results['gt_seg_map'] == self.gt_semantic_map[38:262,
88:312]).all()
assert np.equal(results['gt_bboxes'],
np.array([[0, 0, 122, 122], [112, 112, 224,
224]])).all()
assert np.equal(
results['gt_keypoints'],
np.array([[[0, 12, 0]], [[112, 112, 1]], [[212, 187, 1]]])).all()
# test CenterCrop when size is tuple
transform = dict(type='CenterCrop', crop_size=(224, 224))
center_crop_module = TRANSFORMS.build(transform)
results = self.reset_results(results, self.original_img,
self.gt_semantic_map)
results = center_crop_module(results)
assert results['height'] == 224
assert results['width'] == 224
assert (results['img'] == self.original_img[38:262, 88:312, ...]).all()
assert (results['gt_seg_map'] == self.gt_semantic_map[38:262,
88:312]).all()
assert np.equal(results['gt_bboxes'],
np.array([[0, 0, 122, 122], [112, 112, 224,
224]])).all()
assert np.equal(
results['gt_keypoints'],
np.array([[[0, 12, 0]], [[112, 112, 1]], [[212, 187, 1]]])).all()
# test CenterCrop when crop_height != crop_width
transform = dict(type='CenterCrop', crop_size=(224, 256))
center_crop_module = TRANSFORMS.build(transform)
results = self.reset_results(results, self.original_img,
self.gt_semantic_map)
results = center_crop_module(results)
assert results['height'] == 256
assert results['width'] == 224
assert (results['img'] == self.original_img[22:278, 88:312, ...]).all()
assert (results['gt_seg_map'] == self.gt_semantic_map[22:278,
88:312]).all()
assert np.equal(results['gt_bboxes'],
np.array([[0, 0, 122, 138], [112, 128, 224,
256]])).all()
assert np.equal(
results['gt_keypoints'],
np.array([[[0, 28, 0]], [[112, 128, 1]], [[212, 203, 1]]])).all()
# test CenterCrop when crop_size is equal to img.shape
img_height, img_width, _ = self.original_img.shape
transform = dict(type='CenterCrop', crop_size=(img_width, img_height))
center_crop_module = TRANSFORMS.build(transform)
results = self.reset_results(results, self.original_img,
self.gt_semantic_map)
results = center_crop_module(results)
assert results['height'] == 300
assert results['width'] == 400
assert (results['img'] == self.original_img).all()
assert (results['gt_seg_map'] == self.gt_semantic_map).all()
assert np.equal(results['gt_bboxes'],
np.array([[0, 0, 210, 160], [200, 150, 400,
300]])).all()
assert np.equal(
results['gt_keypoints'],
np.array([[[20, 50, 1]], [[200, 150, 1]], [[300, 225, 1]]])).all()
# test CenterCrop when crop_size is larger than img.shape
transform = dict(
type='CenterCrop', crop_size=(img_width * 2, img_height * 2))
center_crop_module = TRANSFORMS.build(transform)
results = self.reset_results(results, self.original_img,
self.gt_semantic_map)
results = center_crop_module(results)
assert results['height'] == 300
assert results['width'] == 400
assert (results['img'] == self.original_img).all()
assert (results['gt_seg_map'] == self.gt_semantic_map).all()
assert np.equal(results['gt_bboxes'],
np.array([[0, 0, 210, 160], [200, 150, 400,
300]])).all()
assert np.equal(
results['gt_keypoints'],
np.array([[[20, 50, 1]], [[200, 150, 1]], [[300, 225, 1]]])).all()
# test with padding
transform = dict(
type='CenterCrop',
crop_size=(img_width // 2, img_height * 2),
auto_pad=True,
pad_cfg=dict(type='Pad', padding_mode='constant', pad_val=12))
center_crop_module = TRANSFORMS.build(transform)
results = self.reset_results(results, self.original_img,
self.gt_semantic_map)
results = center_crop_module(results)
assert results['height'] == 600
assert results['width'] == 200
assert results['img'].shape[:2] == results['gt_seg_map'].shape
assert (results['img'][300:600, 100:300, ...] == 12).all()
assert (results['gt_seg_map'][300:600, 100:300] == 255).all()
assert np.equal(results['gt_bboxes'],
np.array([[0, 0, 110, 160], [100, 150, 200,
300]])).all()
assert np.equal(
results['gt_keypoints'],
np.array([[[0, 50, 0]], [[100, 150, 1]], [[200, 225, 0]]])).all()
transform = dict(
type='CenterCrop',
crop_size=(img_width // 2, img_height * 2),
auto_pad=True,
pad_cfg=dict(
type='Pad',
padding_mode='constant',
pad_val=dict(img=13, seg=33)))
center_crop_module = TRANSFORMS.build(transform)
results = self.reset_results(results, self.original_img,
self.gt_semantic_map)
results = center_crop_module(results)
assert results['height'] == 600
assert results['width'] == 200
assert (results['img'][300:600, 100:300, ...] == 13).all()
assert (results['gt_seg_map'][300:600, 100:300] == 33).all()
assert np.equal(results['gt_bboxes'],
np.array([[0, 0, 110, 160], [100, 150, 200,
300]])).all()
assert np.equal(
results['gt_keypoints'],
np.array([[[0, 50, 0]], [[100, 150, 1]], [[200, 225, 0]]])).all()
# test CenterCrop when crop_width is smaller than img_width
transform = dict(
type='CenterCrop', crop_size=(img_width // 2, img_height))
center_crop_module = TRANSFORMS.build(transform)
results = self.reset_results(results, self.original_img,
self.gt_semantic_map)
results = center_crop_module(results)
assert results['height'] == img_height
assert results['width'] == img_width // 2
assert (results['img'] == self.original_img[:, 100:300, ...]).all()
assert (results['gt_seg_map'] == self.gt_semantic_map[:,
100:300]).all()
assert np.equal(results['gt_bboxes'],
np.array([[0, 0, 110, 160], [100, 150, 200,
300]])).all()
assert np.equal(
results['gt_keypoints'],
np.array([[[0, 50, 0]], [[100, 150, 1]], [[200, 225, 0]]])).all()
# test CenterCrop when crop_height is smaller than img_height
transform = dict(
type='CenterCrop', crop_size=(img_width, img_height // 2))
center_crop_module = TRANSFORMS.build(transform)
results = self.reset_results(results, self.original_img,
self.gt_semantic_map)
results = center_crop_module(results)
assert results['height'] == img_height // 2
assert results['width'] == img_width
assert (results['img'] == self.original_img[75:225, ...]).all()
assert (results['gt_seg_map'] == self.gt_semantic_map[75:225,
...]).all()
assert np.equal(results['gt_bboxes'],
np.array([[0, 0, 210, 85], [200, 75, 400,
150]])).all()
assert np.equal(
results['gt_keypoints'],
np.array([[[20, 0, 0]], [[200, 75, 1]], [[300, 150, 0]]])).all()
@pytest.mark.skipif(
condition=torch is None, reason='No torch in current env')
def test_torchvision_compare(self):
# compare results with torchvision
results = {}
transform = dict(type='CenterCrop', crop_size=224)
center_crop_module = TRANSFORMS.build(transform)
results = self.reset_results(results, self.original_img,
self.gt_semantic_map)
results = center_crop_module(results)
center_crop_module = torchvision.transforms.CenterCrop(size=224)
pil_img = Image.fromarray(self.original_img)
pil_seg = Image.fromarray(self.gt_semantic_map)
cropped_img = center_crop_module(pil_img)
cropped_img = np.array(cropped_img)
cropped_seg = center_crop_module(pil_seg)
cropped_seg = np.array(cropped_seg)
assert np.equal(results['img'], cropped_img).all()
assert np.equal(results['gt_seg_map'], cropped_seg).all()
class TestRandomGrayscale:
@classmethod
def setup_class(cls):
cls.img = np.random.rand(10, 10, 3).astype(np.float32)
def test_repr(self):
# test repr
transform = dict(
type='RandomGrayscale',
prob=1.,
channel_weights=(0.299, 0.587, 0.114),
keep_channels=True)
random_gray_scale_module = TRANSFORMS.build(transform)
assert isinstance(repr(random_gray_scale_module), str)
def test_error(self):
# test invalid argument
transform = dict(type='RandomGrayscale', prob=2)
with pytest.raises(AssertionError):
TRANSFORMS.build(transform)
def test_transform(self):
results = dict()
# test rgb2gray, return the grayscale image with prob = 1.
transform = dict(
type='RandomGrayscale',
prob=1.,
channel_weights=(0.299, 0.587, 0.114),
keep_channels=True)
random_gray_scale_module = TRANSFORMS.build(transform)
results['img'] = copy.deepcopy(self.img)
img = random_gray_scale_module(results)['img']
computed_gray = (
self.img[:, :, 0] * 0.299 + self.img[:, :, 1] * 0.587 +
self.img[:, :, 2] * 0.114)
for i in range(img.shape[2]):
assert_array_almost_equal(img[:, :, i], computed_gray, decimal=4)
assert img.shape == (10, 10, 3)
# test rgb2gray, return the original image with p=0.
transform = dict(type='RandomGrayscale', prob=0.)
random_gray_scale_module = TRANSFORMS.build(transform)
results['img'] = copy.deepcopy(self.img)
img = random_gray_scale_module(results)['img']
assert_array_equal(img, self.img)
assert img.shape == (10, 10, 3)
# test image with one channel
transform = dict(type='RandomGrayscale', prob=1.)
results['img'] = self.img[:, :, 0:1]
random_gray_scale_module = TRANSFORMS.build(transform)
img = random_gray_scale_module(results)['img']
assert_array_equal(img, self.img[:, :, 0:1])
assert img.shape == (10, 10, 1)
@TRANSFORMS.register_module()
class MockPackTaskInputs(BaseTransform):
def __init__(self) -> None:
super().__init__()
def transform(self, results):
packed_results = dict(inputs=results['img'], data_sample=Mock())
return packed_results
class TestMultiScaleFlipAug:
@classmethod
def setup_class(cls):
cls.img = mmcv.imread(
osp.join(osp.dirname(__file__), '../data/color.jpg'), 'color')
cls.original_img = copy.deepcopy(cls.img)
def test_error(self):
# test assertion if img_scale is not tuple or list of tuple
with pytest.raises(AssertionError):
transform = dict(
type='MultiScaleFlipAug', img_scale=[1333, 800], transforms=[])
TRANSFORMS.build(transform)
# test assertion if flip_direction is not str or list of str
with pytest.raises(AssertionError):
transform = dict(
type='MultiScaleFlipAug',
img_scale=[(1333, 800)],
flip_direction=1,
transforms=[])
TRANSFORMS.build(transform)
@pytest.mark.skipif(
condition=torch is None, reason='No torch in current env')
def test_multi_scale_flip_aug(self):
# test with empty transforms
transform = dict(
type='MultiScaleFlipAug',
transforms=[dict(type='MockPackTaskInputs')],
img_scale=[(1333, 800), (800, 600), (640, 480)],
allow_flip=True,
flip_direction=['horizontal', 'vertical', 'diagonal'])
multi_scale_flip_aug_module = TRANSFORMS.build(transform)
results = dict()
results['img'] = copy.deepcopy(self.original_img)
packed_results = multi_scale_flip_aug_module(results)
assert len(packed_results['inputs']) == 12
# test with allow_flip=False
transform = dict(
type='MultiScaleFlipAug',
transforms=[dict(type='MockPackTaskInputs')],
img_scale=[(1333, 800), (800, 600), (640, 480)],
allow_flip=False,
flip_direction=['horizontal', 'vertical', 'diagonal'])
multi_scale_flip_aug_module = TRANSFORMS.build(transform)
results = dict()
results['img'] = copy.deepcopy(self.original_img)
packed_results = multi_scale_flip_aug_module(results)
assert len(packed_results['inputs']) == 3
# test with transforms
img_norm_cfg = dict(
mean=[123.675, 116.28, 103.53],
std=[58.395, 57.12, 57.375],
to_rgb=True)
transforms_cfg = [
dict(type='Normalize', **img_norm_cfg),
dict(type='Pad', size_divisor=32),
dict(type='ImageToTensor', keys=['img']),
dict(type='MockPackTaskInputs')
]
transform = dict(
type='MultiScaleFlipAug',
transforms=transforms_cfg,
img_scale=[(1333, 800), (800, 600), (640, 480)],
allow_flip=True,
flip_direction=['horizontal', 'vertical', 'diagonal'])
multi_scale_flip_aug_module = TRANSFORMS.build(transform)
results = dict()
results['img'] = copy.deepcopy(self.original_img)
packed_results = multi_scale_flip_aug_module(results)
assert len(packed_results['inputs']) == 12
# test with scale_factor
img_norm_cfg = dict(
mean=[123.675, 116.28, 103.53],
std=[58.395, 57.12, 57.375],
to_rgb=True)
transforms_cfg = [
dict(type='Normalize', **img_norm_cfg),
dict(type='Pad', size_divisor=32),
dict(type='ImageToTensor', keys=['img']),
dict(type='MockPackTaskInputs')
]
transform = dict(
type='MultiScaleFlipAug',
transforms=transforms_cfg,
scale_factor=[0.5, 1., 2.],
allow_flip=True,
flip_direction=['horizontal', 'vertical', 'diagonal'])
multi_scale_flip_aug_module = TRANSFORMS.build(transform)
results = dict()
results['img'] = copy.deepcopy(self.original_img)
packed_results = multi_scale_flip_aug_module(results)
assert len(packed_results['inputs']) == 12
# test no resize
img_norm_cfg = dict(
mean=[123.675, 116.28, 103.53],
std=[58.395, 57.12, 57.375],
to_rgb=True)
transforms_cfg = [
dict(type='Normalize', **img_norm_cfg),
dict(type='Pad', size_divisor=32),
dict(type='ImageToTensor', keys=['img']),
dict(type='MockPackTaskInputs')
]
transform = dict(
type='MultiScaleFlipAug',
transforms=transforms_cfg,
allow_flip=True,
flip_direction=['horizontal', 'vertical', 'diagonal'])
multi_scale_flip_aug_module = TRANSFORMS.build(transform)
results = dict()
results['img'] = copy.deepcopy(self.original_img)
packed_results = multi_scale_flip_aug_module(results)
assert len(packed_results['inputs']) == 4
class TestRandomChoiceResize:
@classmethod
def setup_class(cls):
cls.img = mmcv.imread(
osp.join(osp.dirname(__file__), '../data/color.jpg'), 'color')
cls.original_img = copy.deepcopy(cls.img)
def reset_results(self, results):
results['img'] = copy.deepcopy(self.original_img)
results['gt_seg_map'] = copy.deepcopy(self.original_img)
def test_repr(self):
# test repr
transform = dict(
type='RandomChoiceResize', scales=[(1333, 800), (1333, 600)])
random_multiscale_resize = TRANSFORMS.build(transform)
assert isinstance(repr(random_multiscale_resize), str)
def test_error(self):
# test assertion if size is smaller than 0
with pytest.raises(AssertionError):
transform = dict(type='RandomChoiceResize', scales=[0.5, 1, 2])
TRANSFORMS.build(transform)
def test_random_multiscale_resize(self):
results = dict()
# test with one scale
transform = dict(type='RandomChoiceResize', scales=[(1333, 800)])
random_multiscale_resize = TRANSFORMS.build(transform)
self.reset_results(results)
results = random_multiscale_resize(results)
assert results['img'].shape == (800, 1333, 3)
# test with multi scales
_scale_choice = [(1333, 800), (1333, 600)]
transform = dict(type='RandomChoiceResize', scales=_scale_choice)
random_multiscale_resize = TRANSFORMS.build(transform)
self.reset_results(results)
results = random_multiscale_resize(results)
assert (results['img'].shape[1],
results['img'].shape[0]) in _scale_choice
# test keep_ratio
transform = dict(
type='RandomChoiceResize',
scales=[(900, 600)],
resize_cfg=dict(type='Resize', keep_ratio=True))
random_multiscale_resize = TRANSFORMS.build(transform)
self.reset_results(results)
_input_ratio = results['img'].shape[0] / results['img'].shape[1]
results = random_multiscale_resize(results)
_output_ratio = results['img'].shape[0] / results['img'].shape[1]
assert_array_almost_equal(_input_ratio, _output_ratio)
# test clip_object_border
gt_bboxes = [[200, 150, 600, 450]]
transform = dict(
type='RandomChoiceResize',
scales=[(200, 150)],
resize_cfg=dict(type='Resize', clip_object_border=True))
random_multiscale_resize = TRANSFORMS.build(transform)
self.reset_results(results)
results['gt_bboxes'] = np.array(gt_bboxes)
results = random_multiscale_resize(results)
assert results['img'].shape == (150, 200, 3)
assert np.equal(results['gt_bboxes'], np.array([[100, 75, 200,
150]])).all()
transform = dict(
type='RandomChoiceResize',
scales=[(200, 150)],
resize_cfg=dict(type='Resize', clip_object_border=False))
random_multiscale_resize = TRANSFORMS.build(transform)
self.reset_results(results)
results['gt_bboxes'] = np.array(gt_bboxes)
results = random_multiscale_resize(results)
assert results['img'].shape == (150, 200, 3)
assert np.equal(results['gt_bboxes'], np.array([[100, 75, 300,
225]])).all()
class TestRandomFlip:
def test_init(self):
# prob is float
TRANSFORMS = RandomFlip(0.1)
assert TRANSFORMS.prob == 0.1
# prob is None
with pytest.raises(ValueError):
TRANSFORMS = RandomFlip(None)
assert TRANSFORMS.prob is None
# prob is a list
TRANSFORMS = RandomFlip([0.1, 0.2], ['horizontal', 'vertical'])
assert len(TRANSFORMS.prob) == 2
assert len(TRANSFORMS.direction) == 2
# direction is an invalid type
with pytest.raises(ValueError):
TRANSFORMS = RandomFlip(0.1, 1)
# prob is an invalid type
with pytest.raises(ValueError):
TRANSFORMS = RandomFlip('0.1')
def test_transform(self):
results = {
'img': np.random.random((224, 224, 3)),
'gt_bboxes': np.array([[0, 1, 100, 101]]),
'gt_keypoints': np.array([[[100, 100, 1.0]]]),
'gt_seg_map': np.random.random((224, 224, 3))
}
# horizontal flip
TRANSFORMS = RandomFlip([1.0], ['horizontal'])
results_update = TRANSFORMS.transform(copy.deepcopy(results))
assert (results_update['gt_bboxes'] == np.array([[124, 1, 224,
101]])).all()
# diagnal flip
TRANSFORMS = RandomFlip([1.0], ['diagonal'])
results_update = TRANSFORMS.transform(copy.deepcopy(results))
assert (results_update['gt_bboxes'] == np.array([[124, 123, 224,
223]])).all()
# vertical flip
TRANSFORMS = RandomFlip([1.0], ['vertical'])
results_update = TRANSFORMS.transform(copy.deepcopy(results))
assert (results_update['gt_bboxes'] == np.array([[0, 123, 100,
223]])).all()
# horizontal flip when direction is None
TRANSFORMS = RandomFlip(1.0)
results_update = TRANSFORMS.transform(copy.deepcopy(results))
assert (results_update['gt_bboxes'] == np.array([[124, 1, 224,
101]])).all()
TRANSFORMS = RandomFlip(0.0)
results_update = TRANSFORMS.transform(copy.deepcopy(results))
assert (results_update['gt_bboxes'] == np.array([[0, 1, 100,
101]])).all()
# flip direction is invalid in bbox flip
with pytest.raises(ValueError):
TRANSFORMS = RandomFlip(1.0)
results_update = TRANSFORMS.flip_bbox(results['gt_bboxes'],
(224, 224), 'invalid')
# flip direction is invalid in keypoints flip
with pytest.raises(ValueError):
TRANSFORMS = RandomFlip(1.0)
results_update = TRANSFORMS.flip_keypoints(results['gt_keypoints'],
(224, 224), 'invalid')
def test_repr(self):
TRANSFORMS = RandomFlip(0.1)
TRANSFORMS_str = str(TRANSFORMS)
assert isinstance(TRANSFORMS_str, str)
class TestRandomResize:
def test_init(self):
TRANSFORMS = RandomResize(
(224, 224),
(1.0, 2.0),
)
assert TRANSFORMS.scale == (224, 224)
def test_repr(self):
TRANSFORMS = RandomResize(
(224, 224),
(1.0, 2.0),
)
TRANSFORMS_str = str(TRANSFORMS)
assert isinstance(TRANSFORMS_str, str)
def test_transform(self):
# choose target scale from init when override is True
results = {}
TRANSFORMS = RandomResize((224, 224), (1.0, 2.0))
results_update = TRANSFORMS.transform(copy.deepcopy(results))
assert results_update['scale'][0] >= 224 and results_update['scale'][
0] <= 448
assert results_update['scale'][1] >= 224 and results_update['scale'][
1] <= 448
# keep ratio is True
results = {
'img': np.random.random((224, 224, 3)),
'gt_seg_map': np.random.random((224, 224, 3)),
'gt_bboxes': np.array([[0, 0, 112, 112]]),
'gt_keypoints': np.array([[[112, 112]]])
}
TRANSFORMS = RandomResize(
(224, 224), (1.0, 2.0),
resize_cfg=dict(type='Resize', keep_ratio=True))
results_update = TRANSFORMS.transform(copy.deepcopy(results))
assert 224 <= results_update['img_shape'][0]
assert 448 >= results_update['img_shape'][0]
assert 224 <= results_update['img_shape'][1]
assert 448 >= results_update['img_shape'][1]
assert results_update['keep_ratio']
assert results['gt_bboxes'][0][2] >= 112
assert results['gt_bboxes'][0][2] <= 112
# keep ratio is False
TRANSFORMS = RandomResize(
(224, 224), (1.0, 2.0),
resize_cfg=dict(type='Resize', keep_ratio=False))
results_update = TRANSFORMS.transform(copy.deepcopy(results))
# choose target scale from init when override is False and scale is a
# list of tuples
results = {}
TRANSFORMS = RandomResize([(224, 448), (112, 224)],
resize_cfg=dict(
type='Resize', keep_ratio=True))
results_update = TRANSFORMS.transform(copy.deepcopy(results))
assert results_update['scale'][0] >= 224 and results_update['scale'][
0] <= 448
assert results_update['scale'][1] >= 112 and results_update['scale'][
1] <= 224
# the type of scale is invalid in init
with pytest.raises(NotImplementedError):
results = {}
TRANSFORMS = RandomResize([(224, 448), [112, 224]],
resize_cfg=dict(
type='Resize', keep_ratio=True))
results_update = TRANSFORMS.transform(copy.deepcopy(results))