Files
2026-07-13 12:46:08 +08:00

1120 lines
36 KiB
Python

from __future__ import print_function, division, absolute_import
import sys
# unittest only added in 3.4 self.subTest()
if sys.version_info[0] < 3 or sys.version_info[1] < 4:
import unittest2 as unittest
else:
import unittest
# unittest.mock is not available in 2.7 (though unittest2 might contain it?)
try:
import unittest.mock as mock
except ImportError:
import mock
import numpy as np
import six.moves as sm
from imgaug import augmenters as iaa
from imgaug import parameters as iap
from imgaug import dtypes as iadt
from imgaug import random as iarandom
from imgaug.testutils import reseed, runtest_pickleable_uint8_img
# TODO add tests for EdgeDetect
# TODO add tests for DirectedEdgeDetect
class Test_convolve(unittest.TestCase):
def test_1x1_identity_matrix_2d_image(self):
image = np.array([
[0, 10, 20],
[30, 40, 50]
], dtype=np.uint8)
matrix = np.float32([
[1.0]
])
image_aug = iaa.convolve(image, matrix)
assert image_aug is not image
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 3)
assert np.array_equal(image_aug, image)
class Test_convolve_(unittest.TestCase):
def test_1x1_identity_matrix_2d_image_small_image_sizes(self):
for height in np.arange(16):
for width in np.arange(16):
shapes = [
(height, width),
(height, width, 1),
(height, width, 3)
]
for shape in shapes:
with self.subTest(shape=shape):
image = np.mod(
np.arange(int(np.prod(shape))).reshape(shape),
255
).astype(np.uint8)
matrix = np.float32([
[1.0]
])
image_aug = iaa.convolve_(np.copy(image), matrix)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == shape
assert np.array_equal(image_aug, image)
def test_1x1_identity_matrix_2d_image(self):
image = np.array([
[0, 10, 20],
[30, 40, 50]
], dtype=np.uint8)
matrix = np.float32([
[1.0]
])
image_aug = iaa.convolve_(np.copy(image), matrix)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 3)
assert np.array_equal(image_aug, image)
def test_2x2_identity_matrix_2d_image(self):
image = np.array([
[0, 10, 20, 30],
[40, 50, 60, 70]
], dtype=np.uint8)
matrix = np.float32([
[0.0, 0.0],
[0.0, 1.0]
])
image_aug = iaa.convolve_(np.copy(image), matrix)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 4)
assert np.array_equal(image_aug, image)
def test_3x3_identity_matrix_2d_image(self):
image = np.array([
[0, 10, 20],
[30, 40, 50]
], dtype=np.uint8)
matrix = np.float32([
[0.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 0.0]
])
image_aug = iaa.convolve_(np.copy(image), matrix)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 3)
assert np.array_equal(image_aug, image)
def test_single_matrix_2d_image(self):
image = np.array([
[0, 10, 20],
[30, 40, 50],
[60, 70, 80]
], dtype=np.uint8)
matrix = np.float32([
[0.0, 1.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 0.0]
])
expected = np.array([
[0+30, 10+40, 20+50],
[30+0, 40+10, 50+20],
[60+30, 70+40, 80+50]
], dtype=np.float32)
image_aug = iaa.convolve_(np.copy(image), matrix)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (3, 3)
assert np.array_equal(image_aug, expected)
def test_single_matrix_3d_image(self):
image = np.array([
[0, 10, 20],
[30, 40, 50]
], dtype=np.uint8)
image = np.tile(image[:, :, np.newaxis], (1, 1, 2))
matrix = np.float32([
[0.0, 0.0, 0.0],
[0.0, 2.0, 0.0],
[0.0, 0.0, 0.0]
])
image_aug = iaa.convolve_(np.copy(image), matrix)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 3, 2)
assert np.array_equal(image_aug, 2*image)
def test_matrix_is_list_of_arrays(self):
image = np.array([
[0, 10, 20],
[30, 40, 50]
], dtype=np.uint8)
image = np.tile(image[:, :, np.newaxis], (1, 1, 2))
matrices = [
np.float32([
[0.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 0.0]
]),
np.float32([
[0.0, 0.0, 0.0],
[0.0, 2.0, 0.0],
[0.0, 0.0, 0.0]
])
]
image_aug = iaa.convolve_(np.copy(image), matrices)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 3, 2)
assert np.array_equal(image_aug[:, :, 0], image[:, :, 0])
assert np.array_equal(image_aug[:, :, 1], 2*image[:, :, 1])
def test_matrix_is_list_containing_none(self):
image = np.array([
[0, 10, 20],
[30, 40, 50]
], dtype=np.uint8)
image = np.tile(image[:, :, np.newaxis], (1, 1, 2))
matrices = [
None,
np.float32([
[0.0, 0.0, 0.0],
[0.0, 2.0, 0.0],
[0.0, 0.0, 0.0]
])
]
image_aug = iaa.convolve_(np.copy(image), matrices)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 3, 2)
assert np.array_equal(image_aug[:, :, 0], image[:, :, 0])
assert np.array_equal(image_aug[:, :, 1], 2*image[:, :, 1])
def test_matrix_is_list_containing_only_none(self):
image = np.array([
[0, 10, 20],
[30, 40, 50]
], dtype=np.uint8)
image = np.tile(image[:, :, np.newaxis], (1, 1, 2))
matrices = [
None,
None
]
image_aug = iaa.convolve_(np.copy(image), matrices)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 3, 2)
assert np.array_equal(image_aug[:, :, 0], image[:, :, 0])
assert np.array_equal(image_aug[:, :, 1], image[:, :, 1])
def test_unusual_channel_numbers(self):
for nb_channels in [1, 2, 3, 4, 5, 10, 512, 513]:
with self.subTest(nb_channels=nb_channels):
image = np.array([
[0, 10, 20],
[30, 40, 50]
], dtype=np.uint8)
image = image[:, :, np.newaxis]
image = np.tile(image, (1, 1, nb_channels))
matrix = np.float32([
[2.0]
])
image_aug = iaa.convolve_(np.copy(image), matrix)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 3, nb_channels)
assert np.array_equal(image_aug, 2*image)
def test_zero_sized_axes(self):
shapes = [
(0, 0),
(0, 1),
(1, 0),
(0, 1, 0),
(1, 0, 0),
(0, 1, 1),
(1, 0, 1)
]
for shape in shapes:
with self.subTest(shape=shape):
image = np.zeros(shape, dtype=np.uint8)
matrix = np.float32([
[2.0]
])
image_aug = iaa.convolve_(np.copy(image), matrix)
assert image_aug.shape == image.shape
def test_view_heightwise(self):
image = np.array([
[0, 10, 20],
[30, 40, 50]
], dtype=np.uint8)
image_view = np.copy(image)[:2, :]
assert image_view.flags["OWNDATA"] is False
matrix = np.float32([
[2.0]
])
image_aug = iaa.convolve_(image_view, matrix)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 3)
assert np.array_equal(image_aug, 2*image)
def test_view_channelwise_1_channel(self):
image = np.array([
[0, 10, 20],
[30, 40, 50]
], dtype=np.uint8)
image = np.tile(image[:, :, np.newaxis], (1, 1, 3))
image[:, :, 0] += 0
image[:, :, 1] += 1
image[:, :, 2] += 2
image_view = np.copy(image)[:, :, [False, True, False]]
assert image_view.flags["OWNDATA"] is False
assert image_view.base.shape == (1, 2, 3)
matrix = np.float32([
[2.0]
])
image_aug = iaa.convolve_(image_view, matrix)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 3, 1)
assert np.array_equal(image_aug, 2*image[:, :, 1:2])
def test_view_channelwise_4_channels(self):
image = np.array([
[0, 10, 20],
[30, 40, 50]
], dtype=np.uint8)
image = np.tile(image[:, :, np.newaxis], (1, 1, 6))
image[:, :, 0] += 0
image[:, :, 1] += 1
image[:, :, 2] += 2
mask = [False, True, True, True, True, False]
image_view = np.copy(image)[:, :, mask]
assert image_view.flags["OWNDATA"] is False
assert image_view.base.shape == (4, 2, 3)
matrix = np.float32([
[2.0]
])
image_aug = iaa.convolve_(image_view, matrix)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 3, 4)
assert np.array_equal(image_aug, 2*image[:, :, mask])
def test_noncontiguous(self):
image = np.array([
[0, 10, 20],
[30, 40, 50]
], dtype=np.uint8)
image_nonc = np.array(image, dtype=np.uint8, order="F")
assert image_nonc.flags["C_CONTIGUOUS"] is False
matrix = np.float32([
[2.0]
])
image_aug = iaa.convolve_(image_nonc, matrix)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == (2, 3)
assert np.array_equal(image_aug, 2*image)
# TODO add test for keypoints once their handling was improved in Convolve
class TestConvolve(unittest.TestCase):
def setUp(self):
reseed()
@property
def img(self):
return np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
], dtype=np.uint8)
def test_matrix_is_none(self):
aug = iaa.Convolve(matrix=None)
observed = aug.augment_image(self.img)
assert np.array_equal(observed, self.img)
def test_matrix_is_lambda_none(self):
def _matrix_generator(_img, _nb_channels, _random_state):
return [None]
aug = iaa.Convolve(matrix=_matrix_generator)
observed = aug.augment_image(self.img)
assert np.array_equal(observed, self.img)
def test_matrix_is_1x1_identity(self):
# matrix is [[1]]
aug = iaa.Convolve(matrix=np.float32([[1]]))
observed = aug.augment_image(self.img)
assert np.array_equal(observed, self.img)
def test_matrix_is_lambda_1x1_identity(self):
def _matrix_generator(_img, _nb_channels, _random_state):
return np.float32([[1]])
aug = iaa.Convolve(matrix=_matrix_generator)
observed = aug.augment_image(self.img)
assert np.array_equal(observed, self.img)
def test_matrix_is_3x3_identity(self):
m = np.float32([
[0, 0, 0],
[0, 1, 0],
[0, 0, 0]
])
aug = iaa.Convolve(matrix=m)
observed = aug.augment_image(self.img)
assert np.array_equal(observed, self.img)
def test_matrix_is_lambda_3x3_identity(self):
def _matrix_generator(_img, _nb_channels, _random_state):
return np.float32([
[0, 0, 0],
[0, 1, 0],
[0, 0, 0]
])
aug = iaa.Convolve(matrix=_matrix_generator)
observed = aug.augment_image(self.img)
assert np.array_equal(observed, self.img)
def test_matrix_is_3x3_two_in_center(self):
m = np.float32([
[0, 0, 0],
[0, 2, 0],
[0, 0, 0]
])
aug = iaa.Convolve(matrix=m)
observed = aug.augment_image(self.img)
assert np.array_equal(observed, 2*self.img)
def test_matrix_is_lambda_3x3_two_in_center(self):
def _matrix_generator(_img, _nb_channels, _random_state):
return np.float32([
[0, 0, 0],
[0, 2, 0],
[0, 0, 0]
])
aug = iaa.Convolve(matrix=_matrix_generator)
observed = aug.augment_image(self.img)
assert np.array_equal(observed, 2*self.img)
def test_matrix_is_3x3_two_in_center_3_channels(self):
m = np.float32([
[0, 0, 0],
[0, 2, 0],
[0, 0, 0]
])
aug = iaa.Convolve(matrix=m)
img3 = np.tile(self.img[..., np.newaxis], (1, 1, 3)) # 3 channels
observed = aug.augment_image(img3)
assert np.array_equal(observed, 2*img3)
def test_matrix_is_lambda_3x3_two_in_center_3_channels(self):
def _matrix_generator(_img, _nb_channels, _random_state):
return np.float32([
[0, 0, 0],
[0, 2, 0],
[0, 0, 0]
])
aug = iaa.Convolve(matrix=_matrix_generator)
img3 = np.tile(self.img[..., np.newaxis], (1, 1, 3)) # 3 channels
observed = aug.augment_image(img3)
assert np.array_equal(observed, 2*img3)
def test_matrix_is_3x3_with_multiple_nonzero_values(self):
m = np.float32([
[0, -1, 0],
[0, 10, 0],
[0, 0, 0]
])
expected = np.uint8([
[10*1+(-1)*4, 10*2+(-1)*5, 10*3+(-1)*6],
[10*4+(-1)*1, 10*5+(-1)*2, 10*6+(-1)*3],
[10*7+(-1)*4, 10*8+(-1)*5, 10*9+(-1)*6]
])
aug = iaa.Convolve(matrix=m)
observed = aug.augment_image(self.img)
assert np.array_equal(observed, expected)
def test_matrix_is_lambda_3x3_with_multiple_nonzero_values(self):
def _matrix_generator(_img, _nb_channels, _random_state):
return np.float32([
[0, -1, 0],
[0, 10, 0],
[0, 0, 0]
])
expected = np.uint8([
[10*1+(-1)*4, 10*2+(-1)*5, 10*3+(-1)*6],
[10*4+(-1)*1, 10*5+(-1)*2, 10*6+(-1)*3],
[10*7+(-1)*4, 10*8+(-1)*5, 10*9+(-1)*6]
])
aug = iaa.Convolve(matrix=_matrix_generator)
observed = aug.augment_image(self.img)
assert np.array_equal(observed, expected)
def test_lambda_with_changing_matrices(self):
# changing matrices when using callable
def _matrix_generator(_img, _nb_channels, random_state):
return np.float32([[
iarandom.polyfill_integers(random_state, 0, 5)
]])
expected = []
for i in sm.xrange(5):
expected.append(self.img * i)
aug = iaa.Convolve(matrix=_matrix_generator)
seen = [False] * 5
for _ in sm.xrange(200):
observed = aug.augment_image(self.img)
found = False
for i, expected_i in enumerate(expected):
if np.array_equal(observed, expected_i):
seen[i] = True
found = True
break
assert found
if all(seen):
break
assert np.all(seen)
def test_matrix_has_bad_datatype(self):
# don't use assertRaisesRegex, because it doesnt exist in 2.7
got_exception = False
try:
_aug = iaa.Convolve(matrix=False)
except Exception as exc:
assert "Expected " in str(exc)
got_exception = True
assert got_exception
def test_zero_sized_axes(self):
shapes = [
(0, 0),
(0, 1),
(1, 0),
(0, 1, 0),
(1, 0, 0),
(0, 1, 1),
(1, 0, 1)
]
for shape in shapes:
with self.subTest(shape=shape):
image = np.zeros(shape, dtype=np.uint8)
aug = iaa.Convolve(matrix=np.float32([[1]]))
image_aug = aug(image=image)
assert image_aug.shape == image.shape
def test_get_parameters(self):
matrix = np.int32([[1]])
aug = iaa.Convolve(matrix=matrix)
params = aug.get_parameters()
assert np.array_equal(params[0], matrix)
assert params[1] == "constant"
def test_other_dtypes_bool_identity_matrix(self):
identity_matrix = np.int64([[1]])
aug = iaa.Convolve(matrix=identity_matrix)
image = np.zeros((3, 3), dtype=bool)
image[1, 1] = True
image_aug = aug.augment_image(image)
assert image.dtype.type == np.bool_
assert np.all(image_aug == image)
def test_other_dtypes_uint_int_identity_matrix(self):
identity_matrix = np.int64([[1]])
aug = iaa.Convolve(matrix=identity_matrix)
for dtype in [np.uint8, np.uint16, np.int8, np.int16]:
image = np.zeros((3, 3), dtype=dtype)
image[1, 1] = 100
image_aug = aug.augment_image(image)
assert image.dtype.type == dtype
assert np.all(image_aug == image)
def test_other_dtypes_float_identity_matrix(self):
identity_matrix = np.int64([[1]])
aug = iaa.Convolve(matrix=identity_matrix)
for dtype in [np.float16, np.float32, np.float64]:
image = np.zeros((3, 3), dtype=dtype)
image[1, 1] = 100.0
image_aug = aug.augment_image(image)
assert image.dtype.type == dtype
assert np.allclose(image_aug, image)
def test_other_dtypes_bool_non_identity_matrix_with_small_values(self):
matrix = np.float64([
[0, 0.6, 0],
[0, 0.4, 0],
[0, 0, 0]
])
aug = iaa.Convolve(matrix=matrix)
image = np.zeros((3, 3), dtype=bool)
image[1, 1] = True
image[2, 1] = True
expected = np.zeros((3, 3), dtype=bool)
expected[0, 1] = True
expected[2, 1] = True
image_aug = aug.augment_image(image)
assert image.dtype.type == np.bool_
assert np.all(image_aug == expected)
def test_other_dtypes_uint_int_non_identity_matrix_with_small_values(self):
matrix = np.float64([
[0, 0.5, 0],
[0, 0.5, 0],
[0, 0, 0]
])
aug = iaa.Convolve(matrix=matrix)
for dtype in [np.uint8, np.uint16, np.int8, np.int16]:
image = np.zeros((3, 3), dtype=dtype)
image[1, 1] = 100
image[2, 1] = 100
image_aug = aug.augment_image(image)
expected = np.zeros((3, 3), dtype=dtype)
expected[0, 1] = int(np.round(100 * 0.5))
expected[1, 1] = int(np.round(100 * 0.5))
expected[2, 1] = int(np.round(100 * 0.5 + 100 * 0.5))
diff = np.abs(
image_aug.astype(np.int64)
- expected.astype(np.int64))
assert image_aug.dtype.type == dtype
assert np.max(diff) <= 2
def test_other_dtypes_float_non_identity_matrix_with_small_values(self):
matrix = np.float64([
[0, 0.5, 0],
[0, 0.5, 0],
[0, 0, 0]
])
aug = iaa.Convolve(matrix=matrix)
for dtype in [np.float16, np.float32, np.float64]:
image = np.zeros((3, 3), dtype=dtype)
image[1, 1] = 100.0
image[2, 1] = 100.0
image_aug = aug.augment_image(image)
expected = np.zeros((3, 3), dtype=dtype)
expected[0, 1] = 100 * 0.5
expected[1, 1] = 100 * 0.5
expected[2, 1] = 100 * 0.5 + 100 * 0.5
diff = np.abs(
image_aug.astype(np.float64) - expected.astype(np.float64)
)
assert image_aug.dtype.type == dtype
assert np.max(diff) < 1.0
def test_other_dtypes_uint_int_non_identity_matrix_with_large_values(self):
matrix = np.float64([
[0, 0.5, 0],
[0, 0.5, 0],
[0, 0, 0]
])
aug = iaa.Convolve(matrix=matrix)
for dtype in [np.uint8, np.uint16, np.int8, np.int16]:
_min_value, center_value, max_value = \
iadt.get_value_range_of_dtype(dtype)
value = int(center_value + 0.4 * max_value)
image = np.zeros((3, 3), dtype=dtype)
image[1, 1] = value
image[2, 1] = value
image_aug = aug.augment_image(image)
expected = np.zeros((3, 3), dtype=dtype)
expected[0, 1] = int(np.round(value * 0.5))
expected[1, 1] = int(np.round(value * 0.5))
expected[2, 1] = int(np.round(value * 0.5 + value * 0.5))
diff = np.abs(
image_aug.astype(np.int64)
- expected.astype(np.int64))
assert image_aug.dtype.type == dtype
assert np.max(diff) <= 2
def test_other_dtypes_float_non_identity_matrix_with_large_values(self):
matrix = np.float64([
[0, 0.5, 0],
[0, 0.5, 0],
[0, 0, 0]
])
aug = iaa.Convolve(matrix=matrix)
for dtype, value in zip([np.float16, np.float32, np.float64],
[5000, 1000*1000, 1000*1000*1000]):
image = np.zeros((3, 3), dtype=dtype)
image[1, 1] = value
image[2, 1] = value
image_aug = aug.augment_image(image)
expected = np.zeros((3, 3), dtype=dtype)
expected[0, 1] = value * 0.5
expected[1, 1] = value * 0.5
expected[2, 1] = value * 0.5 + value * 0.5
diff = np.abs(
image_aug.astype(np.float64) - expected.astype(np.float64))
assert image_aug.dtype.type == dtype
assert np.max(diff) < 1.0
def test_failure_on_invalid_dtypes(self):
# don't use assertRaisesRegex, because it doesnt exist in 2.7
identity_matrix = np.int64([[1]])
aug = iaa.Convolve(matrix=identity_matrix)
for dt in [np.uint32, np.uint64, np.int32, np.int64]:
got_exception = False
try:
_ = aug.augment_image(np.zeros((1, 1), dtype=dt))
except Exception as exc:
assert "forbidden dtype" in str(exc)
got_exception = True
assert got_exception
def test_pickleable__identity_matrix(self):
identity_matrix = np.int64([[1]])
aug = iaa.Convolve(identity_matrix, seed=1)
runtest_pickleable_uint8_img(aug, iterations=20)
def test_pickleable__callback_function(self):
aug = iaa.Convolve(_convolve_pickleable_matrix_generator,
seed=1)
runtest_pickleable_uint8_img(aug, iterations=20)
def _convolve_pickleable_matrix_generator(_img, _nb_channels, random_state):
return np.float32([[random_state.integers(0, 5)]])
class TestSharpen(unittest.TestCase):
def setUp(self):
reseed()
@classmethod
def _compute_sharpened_base_img(cls, lightness, m):
img = np.zeros((3, 3), dtype=np.float32)
k = 1
# note that cv2 uses reflection padding by default
img[0, 0] = (
(m[1, 1] + lightness)/k * 10
+ 4 * (m[0, 0]/k) * 10
+ 4 * (m[2, 2]/k) * 20
)
img[0, 2] = img[0, 0]
img[2, 0] = img[0, 0]
img[2, 2] = img[0, 0]
img[0, 1] = (
(m[1, 1] + lightness)/k * 10
+ 6 * (m[0, 1]/k) * 10
+ 2 * (m[2, 2]/k) * 20
)
img[1, 0] = img[0, 1]
img[1, 2] = img[0, 1]
img[2, 1] = img[0, 1]
img[1, 1] = (
(m[1, 1] + lightness)/k * 20
+ 8 * (m[0, 1]/k) * 10
)
img = np.clip(img, 0, 255).astype(np.uint8)
return img
@property
def base_img(self):
base_img = [[10, 10, 10],
[10, 20, 10],
[10, 10, 10]]
base_img = np.uint8(base_img)
return base_img
@property
def base_img_sharpened(self):
return self._compute_sharpened_base_img(1, self.m)
@property
def m(self):
return np.array([[-1, -1, -1],
[-1, 8, -1],
[-1, -1, -1]], dtype=np.float32)
@property
def m_noop(self):
return np.array([[0, 0, 0],
[0, 1, 0],
[0, 0, 0]], dtype=np.float32)
def test_alpha_zero(self):
aug = iaa.Sharpen(alpha=0, lightness=1)
observed = aug.augment_image(self.base_img)
expected = self.base_img
assert np.allclose(observed, expected)
def test_alpha_one(self):
aug = iaa.Sharpen(alpha=1.0, lightness=1)
observed = aug.augment_image(self.base_img)
expected = self.base_img_sharpened
assert np.allclose(observed, expected)
def test_alpha_050(self):
aug = iaa.Sharpen(alpha=0.5, lightness=1)
observed = aug.augment_image(self.base_img)
expected = self._compute_sharpened_base_img(
0.5*1, 0.5 * self.m_noop + 0.5 * self.m)
assert np.allclose(observed, expected.astype(np.uint8))
def test_alpha_075(self):
aug = iaa.Sharpen(alpha=0.75, lightness=1)
observed = aug.augment_image(self.base_img)
expected = self._compute_sharpened_base_img(
0.75*1, 0.25 * self.m_noop + 0.75 * self.m)
assert np.allclose(observed, expected)
def test_alpha_is_stochastic_parameter(self):
aug = iaa.Sharpen(alpha=iap.Choice([0.5, 1.0]), lightness=1)
observed = aug.augment_image(self.base_img)
expected1 = self._compute_sharpened_base_img(
0.5*1, 0.5 * self.m_noop + 0.5 * self.m)
expected2 = self._compute_sharpened_base_img(
1.0*1, 0.0 * self.m_noop + 1.0 * self.m)
assert (
np.allclose(observed, expected1)
or np.allclose(observed, expected2)
)
def test_failure_if_alpha_has_bad_datatype(self):
# don't use assertRaisesRegex, because it doesnt exist in 2.7
got_exception = False
try:
_ = iaa.Sharpen(alpha="test", lightness=1)
except Exception as exc:
assert "Expected " in str(exc)
got_exception = True
assert got_exception
def test_alpha_1_lightness_2(self):
aug = iaa.Sharpen(alpha=1.0, lightness=2)
observed = aug.augment_image(self.base_img)
expected = self._compute_sharpened_base_img(1.0*2, self.m)
assert np.allclose(observed, expected)
def test_alpha_1_lightness_3(self):
aug = iaa.Sharpen(alpha=1.0, lightness=3)
observed = aug.augment_image(self.base_img)
expected = self._compute_sharpened_base_img(1.0*3, self.m)
assert np.allclose(observed, expected)
def test_alpha_1_lightness_is_stochastic_parameter(self):
aug = iaa.Sharpen(alpha=1.0, lightness=iap.Choice([1.0, 1.5]))
observed = aug.augment_image(self.base_img)
expected1 = self._compute_sharpened_base_img(1.0*1.0, self.m)
expected2 = self._compute_sharpened_base_img(1.0*1.5, self.m)
assert (
np.allclose(observed, expected1)
or np.allclose(observed, expected2)
)
def test_failure_if_lightness_has_bad_datatype(self):
# don't use assertRaisesRegex, because it doesnt exist in 2.7
got_exception = False
try:
_ = iaa.Sharpen(alpha=1.0, lightness="test")
except Exception as exc:
assert "Expected " in str(exc)
got_exception = True
assert got_exception
# this part doesnt really work so far due to nonlinearities resulting
# from clipping to uint8
"""
# alpha range
aug = iaa.Sharpen(alpha=(0.0, 1.0), lightness=1)
base_img = np.copy(base_img)
base_img_sharpened_min = _compute_sharpened_base_img(
0.0*1, 1.0 * m_noop + 0.0 * m)
base_img_sharpened_max = _compute_sharpened_base_img(
1.0*1, 0.0 * m_noop + 1.0 * m)
#distance_max = np.average(
np.abs(
base_img_sharpened.astype(np.float32)
- base_img.astype(np.float32)
)
)
distance_max = np.average(
np.abs(
base_img_sharpened_max
- base_img_sharpened_min
)
)
nb_iterations = 250
distances = []
for _ in sm.xrange(nb_iterations):
observed = aug.augment_image(base_img)
distance = np.average(
np.abs(
observed.astype(np.float32)
- base_img_sharpened_max.astype(np.float32)
)
) / distance_max
distances.append(distance)
print(distances)
print(min(distances), np.average(distances), max(distances))
assert 0 - 1e-4 < min(distances) < 0.1
assert 0.4 < np.average(distances) < 0.6
assert 0.9 < max(distances) < 1.0 + 1e-4
nb_bins = 5
hist, _ = np.histogram(distances, bins=nb_bins, range=(0.0, 1.0),
density=False)
density_expected = 1.0/nb_bins
density_tolerance = 0.05
for nb_samples in hist:
density = nb_samples / nb_iterations
assert (
density_expected - density_tolerance
< density
< density_expected + density_tolerance)
# lightness range
aug = iaa.Sharpen(alpha=1.0, lightness=(0.5, 2.0))
base_img = np.copy(base_img)
base_img_sharpened = _compute_sharpened_base_img(1.0*2.0, m)
distance_max = np.average(
np.abs(
base_img_sharpened.astype(np.int32)
- base_img.astype(np.int32)
)
)
nb_iterations = 250
distances = []
for _ in sm.xrange(nb_iterations):
observed = aug.augment_image(base_img)
distance = np.average(
np.abs(
observed.astype(np.int32)
- base_img.astype(np.int32)
)
) / distance_max
distances.append(distance)
assert 0 - 1e-4 < min(distances) < 0.1
assert 0.4 < np.average(distances) < 0.6
assert 0.9 < max(distances) < 1.0 + 1e-4
nb_bins = 5
hist, _ = np.histogram(distances, bins=nb_bins, range=(0.0, 1.0),
density=False)
density_expected = 1.0/nb_bins
density_tolerance = 0.05
for nb_samples in hist:
density = nb_samples / nb_iterations
assert (
density_expected - density_tolerance
< density
< density_expected + density_tolerance)
"""
def test_pickleable(self):
aug = iaa.Sharpen(alpha=(0.0, 1.0), lightness=(1, 3), seed=1)
runtest_pickleable_uint8_img(aug, iterations=20)
class TestEmboss(unittest.TestCase):
def setUp(self):
reseed()
@classmethod
def _compute_embossed_base_img(cls, img, alpha, strength):
img = np.copy(img)
base_img_embossed = np.zeros((3, 3), dtype=np.float32)
m = np.float32([[-1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
strength_matrix = strength * np.float32([
[-1, -1, 0],
[-1, 0, 1],
[0, 1, 1]
])
ms = m + strength_matrix
for i in range(base_img_embossed.shape[0]):
for j in range(base_img_embossed.shape[1]):
for u in range(ms.shape[0]):
for v in range(ms.shape[1]):
weight = ms[u, v]
inputs_i = abs(i + (u - (ms.shape[0]-1)//2))
inputs_j = abs(j + (v - (ms.shape[1]-1)//2))
if inputs_i >= img.shape[0]:
diff = inputs_i - (img.shape[0]-1)
inputs_i = img.shape[0] - 1 - diff
if inputs_j >= img.shape[1]:
diff = inputs_j - (img.shape[1]-1)
inputs_j = img.shape[1] - 1 - diff
inputs = img[inputs_i, inputs_j]
base_img_embossed[i, j] += inputs * weight
return np.clip(
(1-alpha) * img
+ alpha * base_img_embossed,
0,
255
).astype(np.uint8)
@classmethod
def _allclose(cls, a, b):
return np.max(
a.astype(np.float32)
- b.astype(np.float32)
) <= 2.1
@property
def base_img(self):
return np.array([[10, 10, 10],
[10, 20, 10],
[10, 10, 15]], dtype=np.uint8)
def test_alpha_0_strength_1(self):
aug = iaa.Emboss(alpha=0, strength=1)
observed = aug.augment_image(self.base_img)
expected = self.base_img
assert self._allclose(observed, expected)
def test_alpha_1_strength_1(self):
aug = iaa.Emboss(alpha=1.0, strength=1)
observed = aug.augment_image(self.base_img)
expected = self._compute_embossed_base_img(
self.base_img, alpha=1.0, strength=1)
assert self._allclose(observed, expected)
def test_alpha_050_strength_1(self):
aug = iaa.Emboss(alpha=0.5, strength=1)
observed = aug.augment_image(self.base_img)
expected = self._compute_embossed_base_img(
self.base_img, alpha=0.5, strength=1)
assert self._allclose(observed, expected.astype(np.uint8))
def test_alpha_075_strength_1(self):
aug = iaa.Emboss(alpha=0.75, strength=1)
observed = aug.augment_image(self.base_img)
expected = self._compute_embossed_base_img(
self.base_img, alpha=0.75, strength=1)
assert self._allclose(observed, expected)
def test_alpha_stochastic_parameter_strength_1(self):
aug = iaa.Emboss(alpha=iap.Choice([0.5, 1.0]), strength=1)
observed = aug.augment_image(self.base_img)
expected1 = self._compute_embossed_base_img(
self.base_img, alpha=0.5, strength=1)
expected2 = self._compute_embossed_base_img(
self.base_img, alpha=1.0, strength=1)
assert (
self._allclose(observed, expected1)
or self._allclose(observed, expected2)
)
def test_failure_on_invalid_datatype_for_alpha(self):
# don't use assertRaisesRegex, because it doesnt exist in 2.7
got_exception = False
try:
_ = iaa.Emboss(alpha="test", strength=1)
except Exception as exc:
assert "Expected " in str(exc)
got_exception = True
assert got_exception
def test_alpha_1_strength_2(self):
aug = iaa.Emboss(alpha=1.0, strength=2)
observed = aug.augment_image(self.base_img)
expected = self._compute_embossed_base_img(
self.base_img, alpha=1.0, strength=2)
assert self._allclose(observed, expected)
def test_alpha_1_strength_3(self):
aug = iaa.Emboss(alpha=1.0, strength=3)
observed = aug.augment_image(self.base_img)
expected = self._compute_embossed_base_img(
self.base_img, alpha=1.0, strength=3)
assert self._allclose(observed, expected)
def test_alpha_1_strength_6(self):
aug = iaa.Emboss(alpha=1.0, strength=6)
observed = aug.augment_image(self.base_img)
expected = self._compute_embossed_base_img(
self.base_img, alpha=1.0, strength=6)
assert self._allclose(observed, expected)
def test_alpha_1_strength_stochastic_parameter(self):
aug = iaa.Emboss(alpha=1.0, strength=iap.Choice([1.0, 2.5]))
observed = aug.augment_image(self.base_img)
expected1 = self._compute_embossed_base_img(
self.base_img, alpha=1.0, strength=1.0)
expected2 = self._compute_embossed_base_img(
self.base_img, alpha=1.0, strength=2.5)
assert (
self._allclose(observed, expected1)
or self._allclose(observed, expected2)
)
def test_failure_on_invalid_datatype_for_strength(self):
# don't use assertRaisesRegex, because it doesnt exist in 2.7
got_exception = False
try:
_ = iaa.Emboss(alpha=1.0, strength="test")
except Exception as exc:
assert "Expected " in str(exc)
got_exception = True
assert got_exception
def test_pickleable(self):
aug = iaa.Emboss(alpha=(0.0, 1.0), strength=(1, 3), seed=1)
runtest_pickleable_uint8_img(aug, iterations=20)