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

3601 lines
132 KiB
Python

from __future__ import print_function, division, absolute_import
import warnings
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
try:
import cPickle as pickle
except ImportError:
import pickle
import numpy as np
import six.moves as sm
import imgaug as ia
from imgaug import augmenters as iaa
from imgaug import parameters as iap
from imgaug import dtypes as iadt
from imgaug.augmenters import blend
from imgaug.testutils import (
keypoints_equal, reseed, assert_cbaois_equal,
runtest_pickleable_uint8_img, is_parameter_instance)
from imgaug.augmentables.heatmaps import HeatmapsOnImage
from imgaug.augmentables.segmaps import SegmentationMapsOnImage
from imgaug.augmentables.batches import _BatchInAugmentation
class Test_blend_alpha(unittest.TestCase):
def setUp(self):
reseed()
def test_alpha_is_1(self):
for dtype in ["uint8", "float32"]:
with self.subTest(dtype=dtype):
img_fg = np.full((3, 3, 1), 0, dtype=dtype)
img_bg = np.full((3, 3, 1), 255, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 1.0, eps=0)
assert img_blend.dtype.name == dtype
assert img_blend.shape == (3, 3, 1)
assert np.all(img_blend == 0)
def test_alpha_is_1_2d_arrays(self):
for dtype in ["uint8", "float32"]:
with self.subTest(dtype=dtype):
img_fg = np.full((3, 3), 0, dtype=dtype)
img_bg = np.full((3, 3), 255, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 1.0, eps=0)
assert img_blend.dtype.name == dtype
assert img_blend.shape == (3, 3)
assert np.all(img_blend == 0)
def test_alpha_is_0(self):
for dtype in ["uint8", "float32"]:
with self.subTest(dtype=dtype):
img_fg = np.full((3, 3, 1), 0, dtype=dtype)
img_bg = np.full((3, 3, 1), 255, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 0.0, eps=0)
assert img_blend.dtype.name == dtype
assert img_blend.shape == (3, 3, 1)
assert np.all(img_blend == 255)
def test_alpha_is_0_2d_arrays(self):
for dtype in ["uint8", "float32"]:
with self.subTest(dtype=dtype):
img_fg = np.full((3, 3), 0, dtype=dtype)
img_bg = np.full((3, 3), 255, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 0.0, eps=0)
assert img_blend.dtype.name == dtype
assert img_blend.shape == (3, 3)
assert np.all(img_blend == 255)
def test_alpha_is_030(self):
for dtype in ["uint8", "float32"]:
with self.subTest(dtype=dtype):
img_fg = np.full((3, 3, 1), 0, dtype=dtype)
img_bg = np.full((3, 3, 1), 255, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 0.3, eps=0)
assert img_blend.dtype.name == dtype
assert img_blend.shape == (3, 3, 1)
assert np.allclose(img_blend, 0.7*255, atol=1.01, rtol=0)
def test_alpha_is_030_2d_arrays(self):
for dtype in ["uint8", "float32"]:
with self.subTest(dtype=dtype):
img_fg = np.full((3, 3), 0, dtype=dtype)
img_bg = np.full((3, 3), 255, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 0.3, eps=0)
assert img_blend.dtype.name == dtype
assert img_blend.shape == (3, 3)
assert np.allclose(img_blend, 0.7*255, atol=1.01, rtol=0)
def test_alpha_is_030_with_11c_arrays(self):
for dtype in ["uint8", "float32"]:
for nb_channels in [None, 1, 3]:
with self.subTest(dtype=dtype, nb_channels=nb_channels):
shape = (1, 1, nb_channels)
if nb_channels is None:
shape = shape[0:2]
img_fg = np.full(shape, 0, dtype=dtype)
img_bg = np.full(shape, 255, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 0.3, eps=0)
assert img_blend.dtype.name == dtype
assert img_blend.shape == shape
assert np.allclose(img_blend, 0.7*255, atol=1.01, rtol=0)
def test_channelwise_alpha(self):
for dtype in ["uint8", "float32"]:
with self.subTest(dtype=dtype):
img_fg = np.full((3, 3, 2), 0, dtype=dtype)
img_bg = np.full((3, 3, 2), 255, dtype=dtype)
img_blend = blend.blend_alpha(
img_fg, img_bg, [1.0, 0.0], eps=0)
assert img_blend.dtype.name == dtype
assert img_blend.shape == (3, 3, 2)
assert np.all(img_blend[:, :, 0] == 0)
assert np.all(img_blend[:, :, 1] == 255)
def test_larger_images(self):
sizes = [(4, 4), (16, 16), (64, 64), (128, 128)]
for dtype in ["uint8", "float32"]:
for size in sizes:
shape = size + (3,)
for alphas_shape in [size, size + (1,), size + (3,)]:
with self.subTest(dtype=dtype, shape=shape,
alphas_shape=alphas_shape):
alphas = np.full(alphas_shape, 0.5, dtype=np.float32)
img_fg = np.full(shape, 0, dtype=dtype)
img_bg = np.full(shape, 255, dtype=dtype)
img_blend = blend.blend_alpha(
img_fg, img_bg, alphas, eps=0)
assert img_blend.dtype.name == dtype
assert img_blend.shape == shape
assert np.allclose(img_blend, 128, rtol=0, atol=1.01)
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 dtype in ["uint8", "float32"]:
for shape in shapes:
with self.subTest(dtype=dtype, shape=shape):
image_fg = np.full(shape, 0, dtype=dtype)
image_bg = np.full(shape, 255, dtype=dtype)
image_aug = blend.blend_alpha(image_fg, image_bg, 1.0)
assert np.all(image_aug == 0)
assert image_aug.dtype.name == dtype
assert image_aug.shape == shape
def test_unusual_channel_numbers(self):
shapes = [
(1, 1, 4),
(1, 1, 5),
(1, 1, 512),
(1, 1, 513)
]
for dtype in ["uint8", "float32"]:
for shape in shapes:
with self.subTest(dtype=dtype, shape=shape):
image_fg = np.full(shape, 0, dtype=dtype)
image_bg = np.full(shape, 255, dtype=dtype)
image_aug = blend.blend_alpha(image_fg, image_bg, 1.0)
assert np.all(image_aug == 0)
assert image_aug.dtype.name == dtype
assert image_aug.shape == shape
def test_other_dtypes_bool(self):
img_fg = np.full((3, 3, 1), 0, dtype=bool)
img_bg = np.full((3, 3, 1), 1, dtype=bool)
img_blend = blend.blend_alpha(img_fg, img_bg, 0.3, eps=0)
assert img_blend.dtype.name == "bool"
assert img_blend.shape == (3, 3, 1)
assert np.all(img_blend == 1)
def test_other_dtypes_bool_2d_arrays(self):
img_fg = np.full((3, 3), 0, dtype=bool)
img_bg = np.full((3, 3), 1, dtype=bool)
img_blend = blend.blend_alpha(img_fg, img_bg, 0.3, eps=0)
assert img_blend.dtype.name == "bool"
assert img_blend.shape == (3, 3)
assert np.all(img_blend == 1)
# TODO split this up into multiple tests
def test_other_dtypes_uint_int(self):
try:
high_res_dt = np.float128
dtypes = ["uint8", "uint16", "uint32", "uint64",
"int8", "int16", "int32", "int64"]
except AttributeError:
# uint64 and int64 require float128 in their computation
high_res_dt = np.float64
dtypes = ["uint8", "uint16", "uint32",
"int8", "int16", "int32"]
for dtype in dtypes:
with self.subTest(dtype=dtype):
dtype = np.dtype(dtype)
min_value, center_value, max_value = \
iadt.get_value_range_of_dtype(dtype)
values = [
(0, 0),
(0, 10),
(10, 20),
(min_value, min_value),
(max_value, max_value),
(min_value, max_value),
(min_value, int(center_value)),
(int(center_value), max_value),
(int(center_value + 0.20 * max_value), max_value),
(int(center_value + 0.27 * max_value), max_value),
(int(center_value + 0.40 * max_value), max_value),
(min_value, 0),
(0, max_value)
]
values = values + [(v2, v1) for v1, v2 in values]
for v1, v2 in values:
v1_scalar = np.full((), v1, dtype=dtype)
v2_scalar = np.full((), v2, dtype=dtype)
img_fg = np.full((3, 3, 1), v1, dtype=dtype)
img_bg = np.full((3, 3, 1), v2, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 1.0, eps=0)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (3, 3, 1)
assert np.all(img_blend == v1_scalar)
img_fg = np.full((3, 3, 1), v1, dtype=dtype)
img_bg = np.full((3, 3, 1), v2, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 0.99, eps=0.1)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (3, 3, 1)
assert np.all(img_blend == v1_scalar)
img_fg = np.full((3, 3, 1), v1, dtype=dtype)
img_bg = np.full((3, 3, 1), v2, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 0.0, eps=0)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (3, 3, 1)
assert np.all(img_blend == v2_scalar)
# TODO this test breaks for numpy <1.15 -- why?
for c in sm.xrange(3):
img_fg = np.full((3, 3, c), v1, dtype=dtype)
img_bg = np.full((3, 3, c), v2, dtype=dtype)
img_blend = blend.blend_alpha(
img_fg, img_bg, 0.75, eps=0)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (3, 3, c)
for ci in sm.xrange(c):
v_blend = min(
max(
int(
0.75*high_res_dt(v1)
+ 0.25*high_res_dt(v2)
),
min_value
),
max_value)
diff = (
v_blend - img_blend
if v_blend > img_blend[0, 0, ci]
else img_blend - v_blend)
assert np.all(diff < 1.01)
img_fg = np.full((3, 3, 2), v1, dtype=dtype)
img_bg = np.full((3, 3, 2), v2, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 0.75, eps=0)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (3, 3, 2)
v_blend = min(
max(
int(
0.75 * high_res_dt(v1)
+ 0.25 * high_res_dt(v2)
),
min_value
),
max_value)
diff = (
v_blend - img_blend
if v_blend > img_blend[0, 0, 0]
else img_blend - v_blend
)
assert np.all(diff < 1.01)
img_fg = np.full((3, 3, 2), v1, dtype=dtype)
img_bg = np.full((3, 3, 2), v2, dtype=dtype)
img_blend = blend.blend_alpha(
img_fg, img_bg, [1.0, 0.0], eps=0.1)
assert img_blend.dtype.name == np.dtype(dtype).name
assert img_blend.shape == (3, 3, 2)
assert np.all(img_blend[:, :, 0] == v1_scalar)
assert np.all(img_blend[:, :, 1] == v2_scalar)
# elementwise, alphas.shape = (1, 2)
img_fg = np.full((1, 2, 3), v1, dtype=dtype)
img_bg = np.full((1, 2, 3), v2, dtype=dtype)
alphas = np.zeros((1, 2), dtype=np.float64)
alphas[:, :] = [1.0, 0.0]
img_blend = blend.blend_alpha(img_fg, img_bg, alphas, eps=0)
assert img_blend.dtype.name == np.dtype(dtype).name
assert img_blend.shape == (1, 2, 3)
assert np.all(img_blend[0, 0, :] == v1_scalar)
assert np.all(img_blend[0, 1, :] == v2_scalar)
# elementwise, alphas.shape = (1, 2, 1)
img_fg = np.full((1, 2, 3), v1, dtype=dtype)
img_bg = np.full((1, 2, 3), v2, dtype=dtype)
alphas = np.zeros((1, 2, 1), dtype=np.float64)
alphas[:, :, 0] = [1.0, 0.0]
img_blend = blend.blend_alpha(img_fg, img_bg, alphas, eps=0)
assert img_blend.dtype.name == np.dtype(dtype).name
assert img_blend.shape == (1, 2, 3)
assert np.all(img_blend[0, 0, :] == v1_scalar)
assert np.all(img_blend[0, 1, :] == v2_scalar)
# elementwise, alphas.shape = (1, 2, 3)
img_fg = np.full((1, 2, 3), v1, dtype=dtype)
img_bg = np.full((1, 2, 3), v2, dtype=dtype)
alphas = np.zeros((1, 2, 3), dtype=np.float64)
alphas[:, :, 0] = [1.0, 0.0]
alphas[:, :, 1] = [0.0, 1.0]
alphas[:, :, 2] = [1.0, 0.0]
img_blend = blend.blend_alpha(img_fg, img_bg, alphas, eps=0)
assert img_blend.dtype.name == np.dtype(dtype).name
assert img_blend.shape == (1, 2, 3)
assert np.all(img_blend[0, 0, [0, 2]] == v1_scalar)
assert np.all(img_blend[0, 1, [0, 2]] == v2_scalar)
assert np.all(img_blend[0, 0, 1] == v2_scalar)
assert np.all(img_blend[0, 1, 1] == v1_scalar)
# TODO split this up into multiple tests
def test_other_dtypes_float(self):
try:
high_res_dt = np.float128
dtypes = ["float16", "float32", "float64"]
except AttributeError:
# float64 requires float128 in the computation
high_res_dt = np.float64
dtypes = ["float16", "float32"]
for dtype in dtypes:
with self.subTest(dtype=dtype):
dtype = np.dtype(dtype)
def _allclose(a, b):
atol = 1e-4 if dtype == np.float16 else 1e-8
return np.allclose(a, b, atol=atol, rtol=0)
isize = np.dtype(dtype).itemsize
max_value = 1000 ** (isize - 1)
min_value = -max_value
center_value = 0
values = [
(0, 0),
(0, 10),
(10, 20),
(min_value, min_value),
(max_value, max_value),
(min_value, max_value),
(min_value, center_value),
(center_value, max_value),
(center_value + 0.20 * max_value, max_value),
(center_value + 0.27 * max_value, max_value),
(center_value + 0.40 * max_value, max_value),
(min_value, 0),
(0, max_value)
]
values = values + [(v2, v1) for v1, v2 in values]
max_float_dt = high_res_dt
for v1, v2 in values:
v1_scalar = np.full((), v1, dtype=dtype)
v2_scalar = np.full((), v2, dtype=dtype)
img_fg = np.full((3, 3, 1), v1, dtype=dtype)
img_bg = np.full((3, 3, 1), v2, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 1.0, eps=0)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (3, 3, 1)
assert _allclose(img_blend, max_float_dt(v1))
img_fg = np.full((3, 3, 1), v1, dtype=dtype)
img_bg = np.full((3, 3, 1), v2, dtype=dtype)
img_blend = blend.blend_alpha(
img_fg, img_bg, 0.99, eps=0.1)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (3, 3, 1)
assert _allclose(img_blend, max_float_dt(v1))
img_fg = np.full((3, 3, 1), v1, dtype=dtype)
img_bg = np.full((3, 3, 1), v2, dtype=dtype)
img_blend = blend.blend_alpha(img_fg, img_bg, 0.0, eps=0)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (3, 3, 1)
assert _allclose(img_blend, max_float_dt(v2))
for c in sm.xrange(3):
img_fg = np.full((3, 3, c), v1, dtype=dtype)
img_bg = np.full((3, 3, c), v2, dtype=dtype)
img_blend = blend.blend_alpha(
img_fg, img_bg, 0.75, eps=0)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (3, 3, c)
assert _allclose(
img_blend,
0.75*max_float_dt(v1) + 0.25*max_float_dt(v2)
)
img_fg = np.full((3, 3, 2), v1, dtype=dtype)
img_bg = np.full((3, 3, 2), v2, dtype=dtype)
img_blend = blend.blend_alpha(
img_fg, img_bg, [1.0, 0.0], eps=0.1)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (3, 3, 2)
assert _allclose(img_blend[:, :, 0], max_float_dt(v1))
assert _allclose(img_blend[:, :, 1], max_float_dt(v2))
# elementwise, alphas.shape = (1, 2)
img_fg = np.full((1, 2, 3), v1, dtype=dtype)
img_bg = np.full((1, 2, 3), v2, dtype=dtype)
alphas = np.zeros((1, 2), dtype=np.float64)
alphas[:, :] = [1.0, 0.0]
img_blend = blend.blend_alpha(
img_fg, img_bg, alphas, eps=0)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (1, 2, 3)
assert _allclose(img_blend[0, 0, :], v1_scalar)
assert _allclose(img_blend[0, 1, :], v2_scalar)
# elementwise, alphas.shape = (1, 2, 1)
img_fg = np.full((1, 2, 3), v1, dtype=dtype)
img_bg = np.full((1, 2, 3), v2, dtype=dtype)
alphas = np.zeros((1, 2, 1), dtype=np.float64)
alphas[:, :, 0] = [1.0, 0.0]
img_blend = blend.blend_alpha(
img_fg, img_bg, alphas, eps=0)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (1, 2, 3)
assert _allclose(img_blend[0, 0, :], v1_scalar)
assert _allclose(img_blend[0, 1, :], v2_scalar)
# elementwise, alphas.shape = (1, 2, 3)
img_fg = np.full((1, 2, 3), v1, dtype=dtype)
img_bg = np.full((1, 2, 3), v2, dtype=dtype)
alphas = np.zeros((1, 2, 3), dtype=np.float64)
alphas[:, :, 0] = [1.0, 0.0]
alphas[:, :, 1] = [0.0, 1.0]
alphas[:, :, 2] = [1.0, 0.0]
img_blend = blend.blend_alpha(
img_fg, img_bg, alphas, eps=0)
assert img_blend.dtype.name == np.dtype(dtype)
assert img_blend.shape == (1, 2, 3)
assert _allclose(img_blend[0, 0, [0, 2]], v1_scalar)
assert _allclose(img_blend[0, 1, [0, 2]], v2_scalar)
assert _allclose(img_blend[0, 0, 1], v2_scalar)
assert _allclose(img_blend[0, 1, 1], v1_scalar)
class TestAlpha(unittest.TestCase):
def test_deprecation_warning(self):
aug1 = iaa.Sequential([])
aug2 = iaa.Sequential([])
with warnings.catch_warnings(record=True) as caught_warnings:
warnings.simplefilter("always")
aug = iaa.Alpha(0.75, first=aug1, second=aug2)
assert (
"is deprecated"
in str(caught_warnings[-1].message)
)
assert isinstance(aug, iaa.BlendAlpha)
assert np.isclose(aug.factor.value, 0.75)
assert aug.foreground is aug1
assert aug.background is aug2
class TestBlendAlpha(unittest.TestCase):
def setUp(self):
reseed()
@property
def image(self):
base_img = np.zeros((3, 3, 1), dtype=np.uint8)
return base_img
@property
def heatmaps(self):
heatmaps_arr = np.float32([[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0],
[0.0, 1.0, 1.0]])
return HeatmapsOnImage(heatmaps_arr, shape=(3, 3, 3))
@property
def heatmaps_r1(self):
heatmaps_arr_r1 = np.float32([[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
[0.0, 0.0, 1.0]])
return HeatmapsOnImage(heatmaps_arr_r1, shape=(3, 3, 3))
@property
def heatmaps_l1(self):
heatmaps_arr_l1 = np.float32([[0.0, 1.0, 0.0],
[0.0, 1.0, 0.0],
[1.0, 1.0, 0.0]])
return HeatmapsOnImage(heatmaps_arr_l1, shape=(3, 3, 3))
@property
def segmaps(self):
segmaps_arr = np.int32([[0, 0, 1],
[0, 0, 1],
[0, 1, 1]])
return SegmentationMapsOnImage(segmaps_arr, shape=(3, 3, 3))
@property
def segmaps_r1(self):
segmaps_arr_r1 = np.int32([[0, 0, 0],
[0, 0, 0],
[0, 0, 1]])
return SegmentationMapsOnImage(segmaps_arr_r1, shape=(3, 3, 3))
@property
def segmaps_l1(self):
segmaps_arr_l1 = np.int32([[0, 1, 0],
[0, 1, 0],
[1, 1, 0]])
return SegmentationMapsOnImage(segmaps_arr_l1, shape=(3, 3, 3))
@property
def kpsoi(self):
kps = [ia.Keypoint(x=5, y=10), ia.Keypoint(x=6, y=11)]
return ia.KeypointsOnImage(kps, shape=(20, 20, 3))
@property
def psoi(self):
ps = [ia.Polygon([(5, 5), (10, 5), (10, 10)])]
return ia.PolygonsOnImage(ps, shape=(20, 20, 3))
@property
def lsoi(self):
lss = [ia.LineString([(5, 5), (10, 5), (10, 10)])]
return ia.LineStringsOnImage(lss, shape=(20, 20, 3))
@property
def bbsoi(self):
bbs = [ia.BoundingBox(x1=5, y1=6, x2=7, y2=8)]
return ia.BoundingBoxesOnImage(bbs, shape=(20, 20, 3))
def test_images_factor_is_1(self):
aug = iaa.BlendAlpha(1, iaa.Add(10), iaa.Add(20))
observed = aug.augment_image(self.image)
expected = np.round(self.image + 10).astype(np.uint8)
assert np.allclose(observed, expected)
def test_heatmaps_factor_is_1_with_affines_and_per_channel(self):
for per_channel in [False, True]:
with self.subTest(per_channel=per_channel):
aug = iaa.BlendAlpha(
1,
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"x": -1}),
per_channel=per_channel)
observed = aug.augment_heatmaps([self.heatmaps])[0]
assert observed.shape == self.heatmaps.shape
assert 0 - 1e-6 < self.heatmaps.min_value < 0 + 1e-6
assert 1 - 1e-6 < self.heatmaps.max_value < 1 + 1e-6
assert np.allclose(observed.get_arr(),
self.heatmaps_r1.get_arr())
def test_segmaps_factor_is_1_with_affines_and_per_channel(self):
for per_channel in [False, True]:
with self.subTest(per_channel=per_channel):
aug = iaa.BlendAlpha(
1,
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"x": -1}),
per_channel=per_channel)
observed = aug.augment_segmentation_maps([self.segmaps])[0]
assert observed.shape == self.segmaps.shape
assert np.array_equal(observed.get_arr(),
self.segmaps_r1.get_arr())
def test_images_factor_is_0(self):
aug = iaa.BlendAlpha(0, iaa.Add(10), iaa.Add(20))
observed = aug.augment_image(self.image)
expected = np.round(self.image + 20).astype(np.uint8)
assert np.allclose(observed, expected)
def test_heatmaps_factor_is_0_with_affines_and_per_channel(self):
for per_channel in [False, True]:
with self.subTest(per_channel=per_channel):
aug = iaa.BlendAlpha(
0,
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"x": -1}),
per_channel=per_channel)
observed = aug.augment_heatmaps([self.heatmaps])[0]
assert observed.shape == self.heatmaps.shape
assert 0 - 1e-6 < self.heatmaps.min_value < 0 + 1e-6
assert 1 - 1e-6 < self.heatmaps.max_value < 1 + 1e-6
assert np.allclose(observed.get_arr(),
self.heatmaps_l1.get_arr())
def test_segmaps_factor_is_0_with_affines_and_per_channel(self):
for per_channel in [False, True]:
with self.subTest(per_channel=per_channel):
aug = iaa.BlendAlpha(
0,
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"x": -1}),
per_channel=per_channel)
observed = aug.augment_segmentation_maps([self.segmaps])[0]
assert observed.shape == self.segmaps.shape
assert np.array_equal(observed.get_arr(),
self.segmaps_l1.get_arr())
def test_images_factor_is_075(self):
aug = iaa.BlendAlpha(0.75, iaa.Add(10), iaa.Add(20))
observed = aug.augment_image(self.image)
expected = np.round(
self.image
+ 0.75 * 10
+ 0.25 * 20
).astype(np.uint8)
assert np.allclose(observed, expected)
def test_images_factor_is_075_fg_branch_is_none(self):
aug = iaa.BlendAlpha(0.75, None, iaa.Add(20))
observed = aug.augment_image(self.image + 10)
expected = np.round(
self.image
+ 0.75 * 10
+ 0.25 * (10 + 20)
).astype(np.uint8)
assert np.allclose(observed, expected)
def test_images_factor_is_075_bg_branch_is_none(self):
aug = iaa.BlendAlpha(0.75, iaa.Add(10), None)
observed = aug.augment_image(self.image + 10)
expected = np.round(
self.image
+ 0.75 * (10 + 10)
+ 0.25 * 10
).astype(np.uint8)
assert np.allclose(observed, expected)
def test_images_factor_is_tuple(self):
image = np.zeros((1, 2, 1), dtype=np.uint8)
nb_iterations = 1000
aug = iaa.BlendAlpha((0.0, 1.0), iaa.Add(10), iaa.Add(110))
values = []
for _ in sm.xrange(nb_iterations):
observed = aug.augment_image(image)
observed_val = np.round(np.average(observed)) - 10
values.append(observed_val / 100)
nb_bins = 5
hist, _ = np.histogram(values, 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 np.isclose(density, density_expected,
rtol=0, atol=density_tolerance)
def test_bad_datatype_for_factor_fails(self):
got_exception = False
try:
_ = iaa.BlendAlpha(False, iaa.Add(10), None)
except Exception as exc:
assert "Expected " in str(exc)
got_exception = True
assert got_exception
def test_images_with_per_channel_in_both_alpha_and_child(self):
image = np.zeros((1, 1, 1000), dtype=np.uint8)
aug = iaa.BlendAlpha(
1.0,
iaa.Add((0, 100), per_channel=True),
None,
per_channel=True)
observed = aug.augment_image(image)
uq = np.unique(observed)
assert len(uq) > 1
assert np.max(observed) > 80
assert np.min(observed) < 20
def test_images_with_per_channel_in_alpha_and_tuple_as_factor(self):
image = np.zeros((1, 1, 1000), dtype=np.uint8)
aug = iaa.BlendAlpha(
(0.0, 1.0),
iaa.Add(100),
None,
per_channel=True)
observed = aug.augment_image(image)
uq = np.unique(observed)
assert len(uq) > 1
assert np.max(observed) > 80
assert np.min(observed) < 20
def test_images_float_as_per_channel_tuple_as_factor_two_branches(self):
aug = iaa.BlendAlpha(
(0.0, 1.0),
iaa.Add(100),
iaa.Add(0),
per_channel=0.5)
seen = [0, 0]
for _ in sm.xrange(200):
observed = aug.augment_image(np.zeros((1, 1, 100), dtype=np.uint8))
uq = np.unique(observed)
if len(uq) == 1:
seen[0] += 1
elif len(uq) > 1:
seen[1] += 1
else:
assert False
assert 100 - 50 < seen[0] < 100 + 50
assert 100 - 50 < seen[1] < 100 + 50
def test_bad_datatype_for_per_channel_fails(self):
# bad datatype for per_channel
got_exception = False
try:
_ = iaa.BlendAlpha(0.5, iaa.Add(10), None, per_channel="test")
except Exception as exc:
assert "Expected " in str(exc)
got_exception = True
assert got_exception
def test_hooks_limiting_propagation(self):
aug = iaa.BlendAlpha(0.5, iaa.Add(100), iaa.Add(50), name="AlphaTest")
def propagator(images, augmenter, parents, default):
if "Alpha" in augmenter.name:
return False
else:
return default
hooks = ia.HooksImages(propagator=propagator)
image = np.zeros((10, 10, 3), dtype=np.uint8) + 1
observed = aug.augment_image(image, hooks=hooks)
assert np.array_equal(observed, image)
def test_keypoints_factor_is_1(self):
self._test_cba_factor_is_1("augment_keypoints", self.kpsoi)
def test_keypoints_factor_is_0501(self):
self._test_cba_factor_is_0501("augment_keypoints", self.kpsoi)
def test_keypoints_factor_is_0(self):
self._test_cba_factor_is_0("augment_keypoints", self.kpsoi)
def test_keypoints_factor_is_0499(self):
self._test_cba_factor_is_0499("augment_keypoints", self.kpsoi)
def test_keypoints_factor_is_1_with_per_channel(self):
self._test_cba_factor_is_1_and_per_channel(
"augment_keypoints", self.kpsoi)
def test_keypoints_factor_is_0_with_per_channel(self):
self._test_cba_factor_is_0_and_per_channel(
"augment_keypoints", self.kpsoi)
def test_keypoints_factor_is_choice_of_vals_close_to_050_per_channel(self):
self._test_cba_factor_is_choice_around_050_and_per_channel(
"augment_keypoints", self.kpsoi)
def test_keypoints_are_empty(self):
self._test_empty_cba(
"augment_keypoints", ia.KeypointsOnImage([], shape=(1, 2, 3)))
def test_keypoints_hooks_limit_propagation(self):
self._test_cba_hooks_limit_propagation(
"augment_keypoints", self.kpsoi)
def test_polygons_factor_is_1(self):
self._test_cba_factor_is_1("augment_polygons", self.psoi)
def test_polygons_factor_is_0501(self):
self._test_cba_factor_is_0501("augment_polygons", self.psoi)
def test_polygons_factor_is_0(self):
self._test_cba_factor_is_0("augment_polygons", self.psoi)
def test_polygons_factor_is_0499(self):
self._test_cba_factor_is_0499("augment_polygons", self.psoi)
def test_polygons_factor_is_1_and_per_channel(self):
self._test_cba_factor_is_1_and_per_channel(
"augment_polygons", self.psoi)
def test_polygons_factor_is_0_and_per_channel(self):
self._test_cba_factor_is_0_and_per_channel(
"augment_polygons", self.psoi)
def test_polygons_factor_is_choice_around_050_and_per_channel(self):
self._test_cba_factor_is_choice_around_050_and_per_channel(
"augment_polygons", self.psoi
)
def test_empty_polygons(self):
return self._test_empty_cba(
"augment_polygons", ia.PolygonsOnImage([], shape=(1, 2, 3)))
def test_polygons_hooks_limit_propagation(self):
return self._test_cba_hooks_limit_propagation(
"augment_polygons", self.psoi)
def test_line_strings_factor_is_1(self):
self._test_cba_factor_is_1("augment_line_strings", self.lsoi)
def test_line_strings_factor_is_0501(self):
self._test_cba_factor_is_0501("augment_line_strings", self.lsoi)
def test_line_strings_factor_is_0(self):
self._test_cba_factor_is_0("augment_line_strings", self.lsoi)
def test_line_strings_factor_is_0499(self):
self._test_cba_factor_is_0499("augment_line_strings", self.lsoi)
def test_line_strings_factor_is_1_and_per_channel(self):
self._test_cba_factor_is_1_and_per_channel(
"augment_line_strings", self.lsoi)
def test_line_strings_factor_is_0_and_per_channel(self):
self._test_cba_factor_is_0_and_per_channel(
"augment_line_strings", self.lsoi)
def test_line_strings_factor_is_choice_around_050_and_per_channel(self):
self._test_cba_factor_is_choice_around_050_and_per_channel(
"augment_line_strings", self.lsoi
)
def test_empty_line_strings(self):
return self._test_empty_cba(
"augment_line_strings",
ia.LineStringsOnImage([], shape=(1, 2, 3)))
def test_line_strings_hooks_limit_propagation(self):
return self._test_cba_hooks_limit_propagation(
"augment_line_strings", self.lsoi)
def test_bounding_boxes_factor_is_1(self):
self._test_cba_factor_is_1("augment_bounding_boxes", self.bbsoi)
def test_bounding_boxes_factor_is_0501(self):
self._test_cba_factor_is_0501("augment_bounding_boxes", self.bbsoi)
def test_bounding_boxes_factor_is_0(self):
self._test_cba_factor_is_0("augment_bounding_boxes", self.bbsoi)
def test_bounding_boxes_factor_is_0499(self):
self._test_cba_factor_is_0499("augment_bounding_boxes", self.bbsoi)
def test_bounding_boxes_factor_is_1_and_per_channel(self):
self._test_cba_factor_is_1_and_per_channel(
"augment_bounding_boxes", self.bbsoi)
def test_bounding_boxes_factor_is_0_and_per_channel(self):
self._test_cba_factor_is_0_and_per_channel(
"augment_bounding_boxes", self.bbsoi)
def test_bounding_boxes_factor_is_choice_around_050_and_per_channel(self):
self._test_cba_factor_is_choice_around_050_and_per_channel(
"augment_bounding_boxes", self.bbsoi
)
def test_empty_bounding_boxes(self):
return self._test_empty_cba(
"augment_bounding_boxes",
ia.BoundingBoxesOnImage([], shape=(1, 2, 3)))
def test_bounding_boxes_hooks_limit_propagation(self):
return self._test_cba_hooks_limit_propagation(
"augment_bounding_boxes", self.bbsoi)
# Tests for CBA (=coordinate based augmentable) below. This currently
# covers keypoints, polygons and bounding boxes.
@classmethod
def _test_cba_factor_is_1(cls, augf_name, cbaoi):
aug = iaa.BlendAlpha(
1.0, iaa.Identity(), iaa.Affine(translate_px={"x": 1}))
observed = getattr(aug, augf_name)([cbaoi])
assert_cbaois_equal(observed[0], cbaoi)
@classmethod
def _test_cba_factor_is_0501(cls, augf_name, cbaoi):
aug = iaa.BlendAlpha(0.501,
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}))
observed = getattr(aug, augf_name)([cbaoi])
assert_cbaois_equal(observed[0], cbaoi)
@classmethod
def _test_cba_factor_is_0(cls, augf_name, cbaoi):
aug = iaa.BlendAlpha(
0.0, iaa.Identity(), iaa.Affine(translate_px={"x": 1}))
observed = getattr(aug, augf_name)([cbaoi])
expected = cbaoi.shift(x=1)
assert_cbaois_equal(observed[0], expected)
@classmethod
def _test_cba_factor_is_0499(cls, augf_name, cbaoi):
aug = iaa.BlendAlpha(0.499,
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}))
observed = getattr(aug, augf_name)([cbaoi])
expected = cbaoi.shift(x=1)
assert_cbaois_equal(observed[0], expected)
@classmethod
def _test_cba_factor_is_1_and_per_channel(cls, augf_name, cbaoi):
aug = iaa.BlendAlpha(
1.0,
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}),
per_channel=True)
observed = getattr(aug, augf_name)([cbaoi])
assert_cbaois_equal(observed[0], cbaoi)
@classmethod
def _test_cba_factor_is_0_and_per_channel(cls, augf_name, cbaoi):
aug = iaa.BlendAlpha(
0.0,
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}),
per_channel=True)
observed = getattr(aug, augf_name)([cbaoi])
expected = cbaoi.shift(x=1)
assert_cbaois_equal(observed[0], expected)
@classmethod
def _test_cba_factor_is_choice_around_050_and_per_channel(
cls, augf_name, cbaoi):
aug = iaa.BlendAlpha(
iap.Choice([0.49, 0.51]),
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}),
per_channel=True)
expected_same = cbaoi.deepcopy()
expected_shifted = cbaoi.shift(x=1)
seen = [0, 0, 0]
for _ in sm.xrange(200):
observed = getattr(aug, augf_name)([cbaoi])[0]
assert len(observed.items) == len(expected_same.items)
assert len(observed.items) == len(expected_shifted.items)
# We use here allclose() instead of coords_almost_equals()
# as the latter one is much slower for polygons and we don't have
# to deal with tricky geometry changes here, just naive shifting.
if np.allclose(observed.items[0].coords,
expected_same.items[0].coords,
rtol=0, atol=0.1):
seen[0] += 1
elif np.allclose(observed.items[0].coords,
expected_shifted.items[0].coords,
rtol=0, atol=0.1):
seen[1] += 1
else:
seen[2] += 1
assert 100 - 50 < seen[0] < 100 + 50
assert 100 - 50 < seen[1] < 100 + 50
assert seen[2] == 0
@classmethod
def _test_empty_cba(cls, augf_name, cbaoi):
# empty CBAs
aug = iaa.BlendAlpha(0.501,
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}))
observed = getattr(aug, augf_name)(cbaoi)
assert len(observed.items) == 0
assert observed.shape == cbaoi.shape
@classmethod
def _test_cba_hooks_limit_propagation(cls, augf_name, cbaoi):
aug = iaa.BlendAlpha(
0.0,
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"y": 1}),
name="AlphaTest")
def propagator(cbaoi_to_aug, augmenter, parents, default):
if "Alpha" in augmenter.name:
return False
else:
return default
# no hooks for polygons yet, so we use HooksKeypoints
hooks = ia.HooksKeypoints(propagator=propagator)
observed = getattr(aug, augf_name)([cbaoi], hooks=hooks)[0]
assert observed.items[0].coords_almost_equals(cbaoi.items[0])
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.full(shape, 0, dtype=np.uint8)
aug = iaa.BlendAlpha(1.0, iaa.Add(1), iaa.Add(100))
image_aug = aug(image=image)
assert np.all(image_aug == 1)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == shape
def test_unusual_channel_numbers(self):
shapes = [
(1, 1, 4),
(1, 1, 5),
(1, 1, 512),
(1, 1, 513)
]
for shape in shapes:
with self.subTest(shape=shape):
image = np.full(shape, 0, dtype=np.uint8)
aug = iaa.BlendAlpha(1.0, iaa.Add(1), iaa.Add(100))
image_aug = aug(image=image)
assert np.all(image_aug == 1)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == shape
def test_get_parameters(self):
fg = iaa.Identity()
bg = iaa.Sequential([iaa.Add(1)])
aug = iaa.BlendAlpha(0.65, fg, bg, per_channel=1)
params = aug.get_parameters()
assert params[0] is aug.factor
assert params[1] is aug.per_channel
assert 0.65 - 1e-6 < params[0].value < 0.65 + 1e-6
assert params[1].value == 1
def test_get_children_lists(self):
fg = iaa.Identity()
bg = iaa.Sequential([iaa.Add(1)])
aug = iaa.BlendAlpha(0.65, fg, bg, per_channel=1)
children_lsts = aug.get_children_lists()
assert len(children_lsts) == 2
assert ia.is_iterable([lst for lst in children_lsts])
assert fg in children_lsts[0]
assert bg == children_lsts[1]
def test_to_deterministic(self):
class _DummyAugmenter(iaa.Identity):
def __init__(self, *args, **kwargs):
super(_DummyAugmenter, self).__init__(*args, **kwargs)
self.deterministic_called = False
def _to_deterministic(self):
self.deterministic_called = True
return self
identity1 = _DummyAugmenter()
identity2 = _DummyAugmenter()
aug = iaa.BlendAlpha(0.5, identity1, identity2)
aug_det = aug.to_deterministic()
assert aug_det.deterministic
assert aug_det.random_state is not aug.random_state
assert aug_det.foreground.deterministic
assert aug_det.background.deterministic
assert identity1.deterministic_called is True
assert identity2.deterministic_called is True
def test_pickleable(self):
aug = iaa.BlendAlpha(
(0.1, 0.9),
iaa.Add((1, 10), seed=1),
iaa.Add((11, 20), seed=2),
per_channel=True,
seed=3)
runtest_pickleable_uint8_img(aug, iterations=10)
class _DummyMaskParameter(iap.StochasticParameter):
def __init__(self, inverted=False):
super(_DummyMaskParameter, self).__init__()
self.inverted = inverted
def _draw_samples(self, size, random_state):
h, w = size[0:2]
nb_channels = 1 if len(size) == 2 else size[2]
assert nb_channels <= 3
result = []
for i in np.arange(nb_channels):
if i == 0:
result.append(np.zeros((h, w), dtype=np.float32))
else:
result.append(np.ones((h, w), dtype=np.float32))
result = np.stack(result, axis=-1)
if len(size) == 2:
result = result[:, :, 0]
if self.inverted:
result = 1.0 - result
return result
class TestAlphaElementwise(unittest.TestCase):
def test_deprecation_warning(self):
aug1 = iaa.Sequential([])
aug2 = iaa.Sequential([])
with warnings.catch_warnings(record=True) as caught_warnings:
warnings.simplefilter("always")
aug = iaa.AlphaElementwise(factor=0.5, first=aug1, second=aug2)
assert (
"is deprecated"
in str(caught_warnings[-1].message)
)
assert isinstance(aug, iaa.BlendAlphaElementwise)
assert np.isclose(aug.factor.value, 0.5)
assert aug.foreground is aug1
assert aug.background is aug2
# TODO add tests for heatmaps and segmaps that differ from the image size
class TestBlendAlphaElementwise(unittest.TestCase):
def setUp(self):
reseed()
@property
def image(self):
base_img = np.zeros((3, 3, 1), dtype=np.uint8)
return base_img
@property
def heatmaps(self):
heatmaps_arr = np.float32([[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0],
[0.0, 1.0, 1.0]])
return HeatmapsOnImage(heatmaps_arr, shape=(3, 3, 3))
@property
def heatmaps_r1(self):
heatmaps_arr_r1 = np.float32([[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0],
[0.0, 0.0, 1.0]])
return HeatmapsOnImage(heatmaps_arr_r1, shape=(3, 3, 3))
@property
def heatmaps_l1(self):
heatmaps_arr_l1 = np.float32([[0.0, 1.0, 0.0],
[0.0, 1.0, 0.0],
[1.0, 1.0, 0.0]])
return HeatmapsOnImage(heatmaps_arr_l1, shape=(3, 3, 3))
@property
def segmaps(self):
segmaps_arr = np.int32([[0, 0, 1],
[0, 0, 1],
[0, 1, 1]])
return SegmentationMapsOnImage(segmaps_arr, shape=(3, 3, 3))
@property
def segmaps_r1(self):
segmaps_arr_r1 = np.int32([[0, 0, 0],
[0, 0, 0],
[0, 0, 1]])
return SegmentationMapsOnImage(segmaps_arr_r1, shape=(3, 3, 3))
@property
def segmaps_l1(self):
segmaps_arr_l1 = np.int32([[0, 1, 0],
[0, 1, 0],
[1, 1, 0]])
return SegmentationMapsOnImage(segmaps_arr_l1, shape=(3, 3, 3))
@property
def kpsoi(self):
kps = [ia.Keypoint(x=5, y=10), ia.Keypoint(x=6, y=11)]
return ia.KeypointsOnImage(kps, shape=(20, 20, 3))
@property
def psoi(self):
ps = [ia.Polygon([(5, 5), (10, 5), (10, 10)])]
return ia.PolygonsOnImage(ps, shape=(20, 20, 3))
@property
def lsoi(self):
lss = [ia.LineString([(5, 5), (10, 5), (10, 10)])]
return ia.LineStringsOnImage(lss, shape=(20, 20, 3))
@property
def bbsoi(self):
bbs = [ia.BoundingBox(x1=5, y1=6, x2=7, y2=8)]
return ia.BoundingBoxesOnImage(bbs, shape=(20, 20, 3))
def test_images_factor_is_1(self):
aug = iaa.BlendAlphaElementwise(1, iaa.Add(10), iaa.Add(20))
observed = aug.augment_image(self.image)
expected = self.image + 10
assert np.allclose(observed, expected)
def test_heatmaps_factor_is_1_with_affines(self):
aug = iaa.BlendAlphaElementwise(
1,
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"x": -1}))
observed = aug.augment_heatmaps([self.heatmaps])[0]
assert observed.shape == (3, 3, 3)
assert 0 - 1e-6 < observed.min_value < 0 + 1e-6
assert 1 - 1e-6 < observed.max_value < 1 + 1e-6
assert np.allclose(observed.get_arr(), self.heatmaps_r1.get_arr())
def test_segmaps_factor_is_1_with_affines(self):
aug = iaa.BlendAlphaElementwise(
1,
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"x": -1}))
observed = aug.augment_segmentation_maps([self.segmaps])[0]
assert observed.shape == (3, 3, 3)
assert np.array_equal(observed.get_arr(), self.segmaps_r1.get_arr())
def test_images_factor_is_0(self):
aug = iaa.BlendAlphaElementwise(0, iaa.Add(10), iaa.Add(20))
observed = aug.augment_image(self.image)
expected = self.image + 20
assert np.allclose(observed, expected)
def test_heatmaps_factor_is_0_with_affines(self):
aug = iaa.BlendAlphaElementwise(
0,
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"x": -1}))
observed = aug.augment_heatmaps([self.heatmaps])[0]
assert observed.shape == (3, 3, 3)
assert 0 - 1e-6 < observed.min_value < 0 + 1e-6
assert 1 - 1e-6 < observed.max_value < 1 + 1e-6
assert np.allclose(observed.get_arr(), self.heatmaps_l1.get_arr())
def test_segmaps_factor_is_0_with_affines(self):
aug = iaa.BlendAlphaElementwise(
0,
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"x": -1}))
observed = aug.augment_segmentation_maps([self.segmaps])[0]
assert observed.shape == (3, 3, 3)
assert np.array_equal(observed.get_arr(), self.segmaps_l1.get_arr())
def test_images_factor_is_075(self):
aug = iaa.BlendAlphaElementwise(0.75, iaa.Add(10), iaa.Add(20))
observed = aug.augment_image(self.image)
expected = np.round(
self.image + 0.75 * 10 + 0.25 * 20
).astype(np.uint8)
assert np.allclose(observed, expected, atol=1.01)
def test_images_factor_is_075_fg_branch_is_none(self):
aug = iaa.BlendAlphaElementwise(0.75, None, iaa.Add(20))
observed = aug.augment_image(self.image + 10)
expected = np.round(
self.image + 0.75 * 10 + 0.25 * (10 + 20)
).astype(np.uint8)
assert np.allclose(observed, expected, atol=1.01)
def test_images_factor_is_075_bg_branch_is_none(self):
aug = iaa.BlendAlphaElementwise(0.75, iaa.Add(10), None)
observed = aug.augment_image(self.image + 10)
expected = np.round(
self.image + 0.75 * (10 + 10) + 0.25 * 10
).astype(np.uint8)
assert np.allclose(observed, expected, atol=1.01)
def test_images_factor_is_tuple(self):
image = np.zeros((100, 100), dtype=np.uint8)
aug = iaa.BlendAlphaElementwise((0.0, 1.0), iaa.Add(10), iaa.Add(110))
observed = (aug.augment_image(image) - 10) / 100
nb_bins = 10
hist, _ = np.histogram(
observed.flatten(), 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 / observed.size
assert np.isclose(density, density_expected,
rtol=0, atol=density_tolerance)
def test_bad_datatype_for_factor_fails(self):
got_exception = False
try:
_ = iaa.BlendAlphaElementwise(False, iaa.Add(10), None)
except Exception as exc:
assert "Expected " in str(exc)
got_exception = True
assert got_exception
def test_images_with_per_channel_in_alpha_and_tuple_as_factor(self):
image = np.zeros((1, 1, 100), dtype=np.uint8)
aug = iaa.BlendAlphaElementwise(
(0.0, 1.0),
iaa.Add(10),
iaa.Add(110),
per_channel=True)
observed = aug.augment_image(image)
assert len(set(observed.flatten())) > 1
def test_bad_datatype_for_per_channel_fails(self):
got_exception = False
try:
_ = iaa.BlendAlphaElementwise(
0.5,
iaa.Add(10),
None,
per_channel="test")
except Exception as exc:
assert "Expected " in str(exc)
got_exception = True
assert got_exception
def test_hooks_limiting_propagation(self):
aug = iaa.BlendAlphaElementwise(
0.5,
iaa.Add(100),
iaa.Add(50),
name="AlphaElementwiseTest")
def propagator(images, augmenter, parents, default):
if "AlphaElementwise" in augmenter.name:
return False
else:
return default
hooks = ia.HooksImages(propagator=propagator)
image = np.zeros((10, 10, 3), dtype=np.uint8) + 10
observed = aug.augment_image(image, hooks=hooks)
assert np.array_equal(observed, image)
def test_heatmaps_and_per_channel_factor_is_zeros(self):
aug = iaa.BlendAlphaElementwise(
_DummyMaskParameter(inverted=False),
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"x": -1}),
per_channel=True)
observed = aug.augment_heatmaps([self.heatmaps])[0]
assert observed.shape == (3, 3, 3)
assert 0 - 1e-6 < observed.min_value < 0 + 1e-6
assert 1 - 1e-6 < observed.max_value < 1 + 1e-6
assert np.allclose(observed.get_arr(), self.heatmaps_r1.get_arr())
def test_heatmaps_and_per_channel_factor_is_ones(self):
aug = iaa.BlendAlphaElementwise(
_DummyMaskParameter(inverted=True),
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"x": -1}),
per_channel=True)
observed = aug.augment_heatmaps([self.heatmaps])[0]
assert observed.shape == (3, 3, 3)
assert 0 - 1e-6 < observed.min_value < 0 + 1e-6
assert 1 - 1e-6 < observed.max_value < 1 + 1e-6
assert np.allclose(observed.get_arr(), self.heatmaps_l1.get_arr())
def test_segmaps_and_per_channel_factor_is_zeros(self):
aug = iaa.BlendAlphaElementwise(
_DummyMaskParameter(inverted=False),
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"x": -1}),
per_channel=True)
observed = aug.augment_segmentation_maps([self.segmaps])[0]
assert observed.shape == (3, 3, 3)
assert np.array_equal(observed.get_arr(), self.segmaps_r1.get_arr())
def test_segmaps_and_per_channel_factor_is_ones(self):
aug = iaa.BlendAlphaElementwise(
_DummyMaskParameter(inverted=True),
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"x": -1}),
per_channel=True)
observed = aug.augment_segmentation_maps([self.segmaps])[0]
assert observed.shape == (3, 3, 3)
assert np.array_equal(observed.get_arr(), self.segmaps_l1.get_arr())
def test_keypoints_factor_is_1(self):
self._test_cba_factor_is_1("augment_keypoints", self.kpsoi)
def test_keypoints_factor_is_0501(self):
self._test_cba_factor_is_0501("augment_keypoints", self.kpsoi)
def test_keypoints_factor_is_0(self):
self._test_cba_factor_is_0("augment_keypoints", self.kpsoi)
def test_keypoints_factor_is_0499(self):
self._test_cba_factor_is_0499("augment_keypoints", self.kpsoi)
def test_keypoints_factor_is_1_with_per_channel(self):
self._test_cba_factor_is_1_and_per_channel(
"augment_keypoints", self.kpsoi)
def test_keypoints_factor_is_0_with_per_channel(self):
self._test_cba_factor_is_0_and_per_channel(
"augment_keypoints", self.kpsoi)
def test_keypoints_factor_is_choice_of_vals_close_050_per_channel(self):
# TODO can this somehow be integrated into the CBA functions below?
aug = iaa.BlendAlpha(
iap.Choice([0.49, 0.51]),
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}),
per_channel=True)
kpsoi = self.kpsoi
expected_same = kpsoi.deepcopy()
expected_both_shifted = kpsoi.shift(x=1)
expected_fg_shifted = ia.KeypointsOnImage(
[kpsoi.keypoints[0].shift(x=1), kpsoi.keypoints[1]],
shape=self.kpsoi.shape)
expected_bg_shifted = ia.KeypointsOnImage(
[kpsoi.keypoints[0], kpsoi.keypoints[1].shift(x=1)],
shape=self.kpsoi.shape)
seen = [0, 0]
for _ in sm.xrange(200):
observed = aug.augment_keypoints([kpsoi])[0]
if keypoints_equal([observed], [expected_same]):
seen[0] += 1
elif keypoints_equal([observed], [expected_both_shifted]):
seen[1] += 1
elif keypoints_equal([observed], [expected_fg_shifted]):
seen[2] += 1
elif keypoints_equal([observed], [expected_bg_shifted]):
seen[3] += 1
else:
assert False
assert 100 - 50 < seen[0] < 100 + 50
assert 100 - 50 < seen[1] < 100 + 50
def test_keypoints_are_empty(self):
kpsoi = ia.KeypointsOnImage([], shape=(1, 2, 3))
self._test_empty_cba("augment_keypoints", kpsoi)
def test_keypoints_hooks_limit_propagation(self):
self._test_cba_hooks_limit_propagation("augment_keypoints", self.kpsoi)
def test_polygons_factor_is_1(self):
self._test_cba_factor_is_1("augment_polygons", self.psoi)
def test_polygons_factor_is_0501(self):
self._test_cba_factor_is_0501("augment_polygons", self.psoi)
def test_polygons_factor_is_0(self):
self._test_cba_factor_is_0("augment_polygons", self.psoi)
def test_polygons_factor_is_0499(self):
self._test_cba_factor_is_0499("augment_polygons", self.psoi)
def test_polygons_factor_is_1_and_per_channel(self):
self._test_cba_factor_is_1_and_per_channel(
"augment_polygons", self.psoi)
def test_polygons_factor_is_0_and_per_channel(self):
self._test_cba_factor_is_0_and_per_channel(
"augment_polygons", self.psoi)
def test_polygons_factor_is_choice_around_050_and_per_channel(self):
# We use more points here to verify the
# either-or-mode (pointwise=False). The probability that all points
# move in the same way be coincidence is extremely low for so many.
ps = [ia.Polygon([(0, 0), (15, 0), (10, 0), (10, 5), (10, 10),
(5, 10), (5, 5), (0, 10), (0, 5), (0, 0)])]
psoi = ia.PolygonsOnImage(ps, shape=(15, 15, 3))
self._test_cba_factor_is_choice_around_050_and_per_channel(
"augment_polygons", psoi, pointwise=False
)
def test_empty_polygons(self):
psoi = ia.PolygonsOnImage([], shape=(1, 2, 3))
self._test_empty_cba("augment_polygons", psoi)
def test_polygons_hooks_limit_propagation(self):
self._test_cba_hooks_limit_propagation("augment_polygons", self.psoi)
def test_line_strings_factor_is_1(self):
self._test_cba_factor_is_1("augment_line_strings", self.lsoi)
def test_line_strings_factor_is_0501(self):
self._test_cba_factor_is_0501("augment_line_strings", self.lsoi)
def test_line_strings_factor_is_0(self):
self._test_cba_factor_is_0("augment_line_strings", self.lsoi)
def test_line_strings_factor_is_0499(self):
self._test_cba_factor_is_0499("augment_line_strings", self.lsoi)
def test_line_strings_factor_is_1_and_per_channel(self):
self._test_cba_factor_is_1_and_per_channel(
"augment_line_strings", self.lsoi)
def test_line_strings_factor_is_0_and_per_channel(self):
self._test_cba_factor_is_0_and_per_channel(
"augment_line_strings", self.lsoi)
def test_line_strings_factor_is_choice_around_050_and_per_channel(self):
# see same polygons test for why self.lsoi is not used here
lss = [ia.LineString([(0, 0), (15, 0), (10, 0), (10, 5), (10, 10),
(5, 10), (5, 5), (0, 10), (0, 5), (0, 0)])]
lsoi = ia.LineStringsOnImage(lss, shape=(15, 15, 3))
self._test_cba_factor_is_choice_around_050_and_per_channel(
"augment_line_strings", lsoi, pointwise=False
)
def test_empty_line_strings(self):
lsoi = ia.LineStringsOnImage([], shape=(1, 2, 3))
self._test_empty_cba("augment_line_strings", lsoi)
def test_line_strings_hooks_limit_propagation(self):
self._test_cba_hooks_limit_propagation(
"augment_line_strings", self.lsoi)
def test_bounding_boxes_factor_is_1(self):
self._test_cba_factor_is_1("augment_bounding_boxes", self.bbsoi)
def test_bounding_boxes_factor_is_0501(self):
self._test_cba_factor_is_0501("augment_bounding_boxes", self.bbsoi)
def test_bounding_boxes_factor_is_0(self):
self._test_cba_factor_is_0("augment_bounding_boxes", self.bbsoi)
def test_bounding_boxes_factor_is_0499(self):
self._test_cba_factor_is_0499("augment_bounding_boxes", self.bbsoi)
def test_bounding_boxes_factor_is_1_and_per_channel(self):
self._test_cba_factor_is_1_and_per_channel(
"augment_bounding_boxes", self.bbsoi)
def test_bounding_boxes_factor_is_0_and_per_channel(self):
self._test_cba_factor_is_0_and_per_channel(
"augment_bounding_boxes", self.bbsoi)
def test_bounding_boxes_factor_is_choice_around_050_and_per_channel(self):
# TODO pointwise=True or False makes no difference here, because
# there aren't enough points (see corresponding polygon test)
self._test_cba_factor_is_choice_around_050_and_per_channel(
"augment_bounding_boxes", self.bbsoi, pointwise=False
)
def test_empty_bounding_boxes(self):
bbsoi = ia.BoundingBoxesOnImage([], shape=(1, 2, 3))
self._test_empty_cba("augment_bounding_boxes", bbsoi)
def test_bounding_boxes_hooks_limit_propagation(self):
self._test_cba_hooks_limit_propagation(
"augment_bounding_boxes", self.bbsoi)
@classmethod
def _test_cba_factor_is_1(cls, augf_name, cbaoi):
aug = iaa.BlendAlphaElementwise(
1.0,
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}))
observed = getattr(aug, augf_name)([cbaoi])
assert_cbaois_equal(observed[0], cbaoi)
@classmethod
def _test_cba_factor_is_0501(cls, augf_name, cbaoi):
aug = iaa.BlendAlphaElementwise(
0.501,
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}))
observed = getattr(aug, augf_name)([cbaoi])
assert_cbaois_equal(observed[0], cbaoi)
@classmethod
def _test_cba_factor_is_0(cls, augf_name, cbaoi):
aug = iaa.BlendAlphaElementwise(
0.0,
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}))
observed = getattr(aug, augf_name)([cbaoi])
expected = cbaoi.shift(x=1)
assert_cbaois_equal(observed[0], expected)
@classmethod
def _test_cba_factor_is_0499(cls, augf_name, cbaoi):
aug = iaa.BlendAlphaElementwise(
0.499,
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}))
observed = getattr(aug, augf_name)([cbaoi])
expected = cbaoi.shift(x=1)
assert_cbaois_equal(observed[0], expected)
@classmethod
def _test_cba_factor_is_1_and_per_channel(cls, augf_name, cbaoi):
aug = iaa.BlendAlphaElementwise(
1.0,
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}),
per_channel=True)
observed = getattr(aug, augf_name)([cbaoi])
assert_cbaois_equal(observed[0], cbaoi)
@classmethod
def _test_cba_factor_is_0_and_per_channel(cls, augf_name, cbaoi):
aug = iaa.BlendAlphaElementwise(
0.0,
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}),
per_channel=True)
observed = getattr(aug, augf_name)([cbaoi])
expected = cbaoi.shift(x=1)
assert_cbaois_equal(observed[0], expected)
@classmethod
def _test_cba_factor_is_choice_around_050_and_per_channel(
cls, augf_name, cbaoi, pointwise):
aug = iaa.BlendAlphaElementwise(
iap.Choice([0.49, 0.51]),
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}),
per_channel=True)
expected_same = cbaoi.deepcopy()
expected_shifted = cbaoi.shift(x=1)
nb_iterations = 400
seen = [0, 0, 0]
for _ in sm.xrange(nb_iterations):
observed = getattr(aug, augf_name)([cbaoi])[0]
# We use here allclose() instead of coords_almost_equals()
# as the latter one is much slower for polygons and we don't have
# to deal with tricky geometry changes here, just naive shifting.
if np.allclose(observed.items[0].coords,
expected_same.items[0].coords,
rtol=0, atol=0.1):
seen[0] += 1
elif np.allclose(observed.items[0].coords,
expected_shifted.items[0].coords,
rtol=0, atol=0.1):
seen[1] += 1
else:
seen[2] += 1
if pointwise:
# This code can be used if the polygon augmentation mode is
# AlphaElementwise._MODE_POINTWISE. Currently it is _MODE_EITHER_OR.
nb_points = len(cbaoi.items[0].coords)
p_all_same = 2 * ((1/2)**nb_points) # all points moved in same way
expected_iter = nb_iterations*p_all_same
expected_iter_notsame = nb_iterations*(1-p_all_same)
atol = nb_iterations * (5*p_all_same)
assert np.isclose(seen[0], expected_iter, rtol=0, atol=atol)
assert np.isclose(seen[1], expected_iter, rtol=0, atol=atol)
assert np.isclose(seen[2], expected_iter_notsame, rtol=0, atol=atol)
else:
expected_iter = nb_iterations*0.5
atol = nb_iterations*0.15
assert np.isclose(seen[0], expected_iter, rtol=0, atol=atol)
assert np.isclose(seen[1], expected_iter, rtol=0, atol=atol)
assert seen[2] == 0
@classmethod
def _test_empty_cba(cls, augf_name, cbaoi):
aug = iaa.BlendAlphaElementwise(
0.501,
iaa.Identity(),
iaa.Affine(translate_px={"x": 1}))
observed = getattr(aug, augf_name)(cbaoi)
assert len(observed.items) == 0
assert observed.shape == (1, 2, 3)
@classmethod
def _test_cba_hooks_limit_propagation(cls, augf_name, cbaoi):
aug = iaa.BlendAlphaElementwise(
0.0,
iaa.Affine(translate_px={"x": 1}),
iaa.Affine(translate_px={"y": 1}),
name="AlphaTest")
def propagator(cbaoi_to_aug, augmenter, parents, default):
if "Alpha" in augmenter.name:
return False
else:
return default
# no hooks for polygons yet, so we use HooksKeypoints
hooks = ia.HooksKeypoints(propagator=propagator)
observed = getattr(aug, augf_name)([cbaoi], hooks=hooks)[0]
assert observed.items[0].coords_almost_equals(cbaoi.items[0])
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.full(shape, 0, dtype=np.uint8)
aug = iaa.BlendAlpha(1.0, iaa.Add(1), iaa.Add(100))
image_aug = aug(image=image)
assert np.all(image_aug == 1)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == shape
def test_unusual_channel_numbers(self):
shapes = [
(1, 1, 4),
(1, 1, 5),
(1, 1, 512),
(1, 1, 513)
]
for shape in shapes:
with self.subTest(shape=shape):
image = np.full(shape, 0, dtype=np.uint8)
aug = iaa.BlendAlpha(1.0, iaa.Add(1), iaa.Add(100))
image_aug = aug(image=image)
assert np.all(image_aug == 1)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == shape
def test_pickleable(self):
aug = iaa.BlendAlphaElementwise(
(0.1, 0.9),
iaa.Add((1, 10), seed=1),
iaa.Add((11, 20), seed=2),
per_channel=True,
seed=3)
runtest_pickleable_uint8_img(aug, iterations=3)
class TestBlendAlphaSomeColors(unittest.TestCase):
def setUp(self):
reseed()
def test___init__(self):
child1 = iaa.Sequential([])
child2 = iaa.Sequential([])
aug = iaa.BlendAlphaSomeColors(child1, child2)
assert aug.foreground is child1
assert aug.background is child2
assert isinstance(aug.mask_generator, iaa.SomeColorsMaskGen)
def test_grayscale_drops_different_colors(self):
image = np.uint8([
[255, 0, 0],
[0, 255, 0],
[0, 0, 255],
[255, 255, 0],
[255, 0, 255],
[0, 255, 255],
[255, 128, 128],
[128, 255, 128],
[128, 128, 255]
]).reshape((1, 9, 3))
image_gray = iaa.Grayscale(1.0)(image=image)
aug = iaa.BlendAlphaSomeColors(iaa.Grayscale(1.0),
nb_bins=256, smoothness=0)
nb_grayscaled = []
for _ in sm.xrange(50):
image_aug = aug(image=image)
grayscaled = np.sum((image_aug == image_gray).astype(np.int32),
axis=2)
assert np.all(np.logical_or(grayscaled == 0, grayscaled == 3))
nb_grayscaled.append(np.sum(grayscaled == 3))
assert len(set(nb_grayscaled)) >= 5
def test_zero_sized_axes(self):
shapes = [
(0, 0, 3),
(0, 1, 3),
(1, 0, 3)
]
for shape in shapes:
with self.subTest(shape=shape):
image = np.full(shape, 0, dtype=np.uint8)
aug = iaa.BlendAlphaSomeColors(iaa.Add(1), iaa.Add(100))
image_aug = aug(image=image)
assert np.all(image_aug == 1)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == shape
def test_pickleable(self):
aug = iaa.BlendAlphaSomeColors(
iaa.Add((1, 10), seed=1),
iaa.Add((11, 20), seed=2),
seed=3)
runtest_pickleable_uint8_img(aug, iterations=3)
class TestBlendAlphaHorizontalLinearGradient(unittest.TestCase):
def setUp(self):
reseed()
def test___init__(self):
child1 = iaa.Sequential([])
child2 = iaa.Sequential([])
aug = iaa.BlendAlphaHorizontalLinearGradient(child1, child2)
assert aug.foreground is child1
assert aug.background is child2
assert isinstance(aug.mask_generator,
iaa.HorizontalLinearGradientMaskGen)
def test_single_image(self):
image = np.full((2, 100, 3), 255, dtype=np.uint8)
image_drop = iaa.TotalDropout(1.0)(image=image)
aug = iaa.BlendAlphaHorizontalLinearGradient(iaa.TotalDropout(1.0),
min_value=0.0,
max_value=1.0,
start_at=0.2,
end_at=0.8)
image_aug = aug(image=image)
assert np.array_equal(image_aug[0, :, :], image_aug[1, :, :])
assert np.array_equal(image_aug[:, :20, :], image[:, :20, :])
assert np.array_equal(image_aug[:, 80:, :], image_drop[:, 80:, :])
assert not np.array_equal(image_aug[:, 20:80, :], image[:, 20:80, :])
assert not np.array_equal(image_aug[:, 20:80, :],
image_drop[:, 20:80, :])
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.full(shape, 0, dtype=np.uint8)
aug = iaa.BlendAlphaHorizontalLinearGradient(
iaa.TotalDropout(1.0))
image_aug = aug(image=image)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == shape
def test_pickleable(self):
aug = iaa.BlendAlphaHorizontalLinearGradient(
iaa.Add((1, 10), seed=1),
iaa.Add((11, 20), seed=2),
seed=3)
runtest_pickleable_uint8_img(aug, iterations=3)
class TestBlendAlphaVerticalLinearGradient(unittest.TestCase):
def setUp(self):
reseed()
def test___init__(self):
child1 = iaa.Sequential([])
child2 = iaa.Sequential([])
aug = iaa.BlendAlphaVerticalLinearGradient(child1, child2)
assert aug.foreground is child1
assert aug.background is child2
assert isinstance(aug.mask_generator,
iaa.VerticalLinearGradientMaskGen)
def test_single_image(self):
image = np.full((100, 2, 3), 255, dtype=np.uint8)
image_drop = iaa.TotalDropout(1.0)(image=image)
aug = iaa.BlendAlphaVerticalLinearGradient(iaa.TotalDropout(1.0),
min_value=0.0,
max_value=1.0,
start_at=0.2,
end_at=0.8)
image_aug = aug(image=image)
assert np.array_equal(image_aug[:, 0, :], image_aug[:, 0, :])
assert np.array_equal(image_aug[:20, :, :], image[:20, :, :])
assert np.array_equal(image_aug[80:, :, :], image_drop[80:, :, :])
assert not np.array_equal(image_aug[20:80, :, :], image[20:80, :, :])
assert not np.array_equal(image_aug[20:80, :, :],
image_drop[20:80, :, :])
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.full(shape, 0, dtype=np.uint8)
aug = iaa.BlendAlphaVerticalLinearGradient(
iaa.TotalDropout(1.0))
image_aug = aug(image=image)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == shape
def test_pickleable(self):
aug = iaa.BlendAlphaVerticalLinearGradient(
iaa.Add((1, 10), seed=1),
iaa.Add((11, 20), seed=2),
seed=3)
runtest_pickleable_uint8_img(aug, iterations=3)
class TestBlendAlphaRegularGrid(unittest.TestCase):
def setUp(self):
reseed()
def test___init__(self):
child1 = iaa.Sequential([])
child2 = iaa.Sequential([])
aug = iaa.BlendAlphaRegularGrid(2, 3, child1, child2, alpha=0.7)
assert aug.mask_generator.nb_rows.value == 2
assert aug.mask_generator.nb_cols.value == 3
assert aug.foreground is child1
assert aug.background is child2
assert isinstance(aug.mask_generator, iaa.RegularGridMaskGen)
assert np.isclose(aug.mask_generator.alpha.value, 0.7)
def test_single_image(self):
image = np.full((2, 6, 3), 255, dtype=np.uint8)
aug = iaa.BlendAlphaRegularGrid(
nb_rows=1, nb_cols=3,
foreground=iaa.TotalDropout(1.0),
alpha=iap.DeterministicList([1.0, 0.0, 1.0]))
image_aug = aug(image=image)
expected = np.copy(image)
expected[:, 0:2, :] = 0
expected[:, 4:6, :] = 0
assert np.array_equal(image_aug, expected)
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.full(shape, 0, dtype=np.uint8)
aug = iaa.BlendAlphaRegularGrid(
nb_rows=2, nb_cols=3, foreground=iaa.TotalDropout(1.0))
image_aug = aug(image=image)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == shape
def test_pickleable(self):
aug = iaa.BlendAlphaRegularGrid(
2, 3,
iaa.Add((1, 10), seed=1),
iaa.Add((11, 20), seed=2),
seed=3)
runtest_pickleable_uint8_img(aug, iterations=3)
class TestBlendAlphaCheckerboard(unittest.TestCase):
def setUp(self):
reseed()
def test___init__(self):
child1 = iaa.Sequential([])
child2 = iaa.Sequential([])
aug = iaa.BlendAlphaCheckerboard(2, 3, child1, child2)
assert aug.mask_generator.nb_rows.value == 2
assert aug.mask_generator.nb_cols.value == 3
assert aug.foreground is child1
assert aug.background is child2
assert isinstance(aug.mask_generator, iaa.CheckerboardMaskGen)
def test_single_image(self):
image = np.full((2, 6, 3), 255, dtype=np.uint8)
aug = iaa.BlendAlphaCheckerboard(nb_rows=1, nb_cols=3,
foreground=iaa.TotalDropout(1.0))
image_aug = aug(image=image)
expected = np.copy(image)
expected[:, 0:2, :] = 0
expected[:, 4:6, :] = 0
assert np.array_equal(image_aug, expected)
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.full(shape, 0, dtype=np.uint8)
aug = iaa.BlendAlphaCheckerboard(
nb_rows=2, nb_cols=3, foreground=iaa.TotalDropout(1.0))
image_aug = aug(image=image)
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == shape
def test_pickleable(self):
aug = iaa.BlendAlphaCheckerboard(
2, 3,
iaa.Add((1, 10), seed=1),
iaa.Add((11, 20), seed=2),
seed=3)
runtest_pickleable_uint8_img(aug, iterations=3)
class TestBlendAlphaSegMapClassIds(unittest.TestCase):
def setUp(self):
reseed()
def test___init__(self):
child1 = iaa.Sequential([])
child2 = iaa.Sequential([])
aug = iaa.BlendAlphaSegMapClassIds(
2,
nb_sample_classes=1,
foreground=child1,
background=child2
)
assert aug.foreground is child1
assert aug.background is child2
assert isinstance(aug.mask_generator,
iaa.SegMapClassIdsMaskGen)
assert aug.mask_generator.class_ids.value == 2
assert aug.mask_generator.nb_sample_classes.value == 1
def test_single_image(self):
image = np.full((10, 10, 3), 255, dtype=np.uint8)
segmap_arr = np.zeros((5, 10, 1), dtype=np.int32)
segmap_arr[0:2, :] = 1
aug = iaa.BlendAlphaSegMapClassIds(
1,
nb_sample_classes=1,
foreground=iaa.TotalDropout(1.0)
)
image_aug, segmap_aug = aug(image=image,
segmentation_maps=[segmap_arr])
assert np.allclose(image_aug[0:4, :, :], 0, rtol=0, atol=1.01)
assert np.allclose(image_aug[4:, :, :], 255, rtol=0, atol=1.01)
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.full(shape, 255, dtype=np.uint8)
segmap_arr = np.zeros((2, 2, 1), dtype=np.int32)
segmap_arr[0, 0] = 2
aug = iaa.BlendAlphaSegMapClassIds(
2,
foreground=iaa.TotalDropout(1.0))
image_aug, segmap_aug = aug(
image=image, segmentation_maps=[segmap_arr])
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == shape
def test_pickleable(self):
shape = (15, 15, 3)
iterations = 3
augmenter = iaa.BlendAlphaSegMapClassIds(
[1, 2],
foreground=iaa.Add((1, 10), seed=1),
background=iaa.Add((11, 20), seed=2),
nb_sample_classes=1,
seed=3)
image = np.mod(np.arange(int(np.prod(shape))), 256).astype(np.uint8)
image = image.reshape(shape)
segmap_arr = np.zeros((15, 15, 1), dtype=np.int32)
segmap_arr[0:2, 0:2] = 1
segmap_arr[4:6, 5:8] = 2
augmenter_pkl = pickle.loads(pickle.dumps(augmenter, protocol=-1))
for _ in np.arange(iterations):
image_aug, sm_aug = augmenter(
image=image, segmentation_maps=[segmap_arr])
image_aug_pkl, sm_aug_pkl = augmenter_pkl(
image=image, segmentation_maps=[segmap_arr])
assert np.array_equal(image_aug, image_aug_pkl)
assert np.array_equal(sm_aug, sm_aug_pkl)
class TestBlendAlphaBoundingBoxes(unittest.TestCase):
def setUp(self):
reseed()
def test___init__(self):
child1 = iaa.Sequential([])
child2 = iaa.Sequential([])
aug = iaa.BlendAlphaBoundingBoxes(
"person",
nb_sample_labels=1,
foreground=child1,
background=child2
)
assert aug.foreground is child1
assert aug.background is child2
assert isinstance(aug.mask_generator,
iaa.BoundingBoxesMaskGen)
assert aug.mask_generator.labels.value == "person"
assert aug.mask_generator.nb_sample_labels.value == 1
def test_single_image(self):
image = np.full((10, 10, 3), 255, dtype=np.uint8)
bbs = [ia.BoundingBox(x1=1, y1=1, x2=5, y2=5, label="bb1"),
ia.BoundingBox(x1=-3, y1=4, x2=20, y2=8, label="bb2")]
aug = iaa.BlendAlphaBoundingBoxes(
["bb1"],
nb_sample_labels=1,
foreground=iaa.Multiply(0.0)
)
image_aug, segmap_aug = aug(image=image,
bounding_boxes=[bbs])
assert np.allclose(image_aug[1:5, 1:5, :], 0, rtol=0, atol=1.01)
assert np.allclose(image_aug[0:1, 0:1, :], 255, rtol=0, atol=1.01)
assert np.allclose(image_aug[5:10, 5:10, :], 255, rtol=0, atol=1.01)
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.full(shape, 255, dtype=np.uint8)
bbs = [ia.BoundingBox(x1=1, y1=1, x2=5, y2=5, label="bb1"),
ia.BoundingBox(x1=-3, y1=4, x2=20, y2=8, label="bb2")]
aug = iaa.BlendAlphaBoundingBoxes(
["bb1"],
foreground=iaa.Multiply(0.0))
image_aug, segmap_aug = aug(
image=image, bounding_boxes=[bbs])
assert image_aug.dtype.name == "uint8"
assert image_aug.shape == shape
def test_pickleable(self):
shape = (15, 15, 3)
iterations = 3
augmenter = iaa.BlendAlphaBoundingBoxes(
["bb1", "bb2", "bb3"],
foreground=iaa.Add((1, 10), seed=1),
background=iaa.Add((11, 20), seed=2),
nb_sample_labels=1,
seed=3)
image = np.mod(np.arange(int(np.prod(shape))), 256).astype(np.uint8)
image = image.reshape(shape)
bbs = [ia.BoundingBox(x1=1, y1=1, x2=5, y2=5, label="bb1"),
ia.BoundingBox(x1=-3, y1=4, x2=20, y2=8, label="bb2")]
augmenter_pkl = pickle.loads(pickle.dumps(augmenter, protocol=-1))
for _ in np.arange(iterations):
image_aug, bbs_aug = augmenter(
image=image, bounding_boxes=[bbs])
image_aug_pkl, bbs_aug_pkl = augmenter_pkl(
image=image, bounding_boxes=[bbs])
assert np.array_equal(image_aug, image_aug_pkl)
class TestStochasticParameterMaskGen(unittest.TestCase):
@classmethod
def _test_draw_masks_nhwc(cls, shape):
batch = _BatchInAugmentation(
images=np.zeros(shape, dtype=np.uint8)
)
values = np.float32([
[0.1, 0.2, 0.3],
[0.4, 0.5, 0.6]
])
param = iap.DeterministicList(values.flatten())
gen = iaa.StochasticParameterMaskGen(param, per_channel=False)
masks = gen.draw_masks(batch, random_state=0)
for i in np.arange(shape[0]):
assert np.allclose(masks[i], values)
def test_draw_masks_hw3_images(self):
self._test_draw_masks_nhwc((2, 2, 3, 3))
def test_draw_masks_hw1_images(self):
self._test_draw_masks_nhwc((2, 2, 3, 1))
def test_draw_masks_hw_images(self):
self._test_draw_masks_nhwc((2, 2, 3))
def test_draw_masks_batch_without_images(self):
bb = ia.BoundingBox(x1=1, y1=2, x2=3, y2=4)
bbsoi1 = ia.BoundingBoxesOnImage([bb], shape=(2, 3, 3))
bbsoi2 = ia.BoundingBoxesOnImage([], shape=(3, 3, 3))
batch = _BatchInAugmentation(
bounding_boxes=[bbsoi1, bbsoi2]
)
# sampling for shape of bbsoi1 will cover row1 and row2, then
# sampling for bbsoi2 will cover row1, row2, row3
# masks are sampled independently per row/image, so it starts over
# again for bbsoi2
values = np.float32([
[0.1, 0.2, 0.3],
[0.4, 0.5, 0.6],
[0.7, 0.8, 0.9]
])
param = iap.DeterministicList(values.flatten())
gen = iaa.StochasticParameterMaskGen(param, per_channel=False)
masks = gen.draw_masks(batch, random_state=0)
expected1 = values[0:2]
expected2 = values[0:3]
assert np.allclose(masks[0], expected1)
assert np.allclose(masks[1], expected2)
def test_per_channel(self):
for per_channel in [True, iap.Deterministic(0.51)]:
batch = _BatchInAugmentation(
images=np.zeros((1, 2, 3, 2), dtype=np.uint8)
)
values = np.float32([
[0.1, 0.2, 0.3],
[0.4, 0.5, 0.6],
[0.7, 0.8, 0.9],
[0.10, 0.11, 0.12]
])
param = iap.DeterministicList(values.flatten())
gen = iaa.StochasticParameterMaskGen(param,
per_channel=per_channel)
masks = gen.draw_masks(batch, random_state=0)
assert np.allclose(masks[0], values.reshape((2, 3, 2)))
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 per_channel in [False, True]:
for shape in shapes:
with self.subTest(per_channel=per_channel, shape=shape):
batch = _BatchInAugmentation(
images=[np.zeros(shape, dtype=np.uint8)]
)
param = iap.Deterministic(1.0)
gen = iaa.StochasticParameterMaskGen(
param, per_channel=per_channel)
masks = gen.draw_masks(batch, random_state=0)
assert len(masks) == 1
if not per_channel:
assert masks[0].shape == shape[0:2]
else:
assert masks[0].shape == shape
class TestSomeColorsMaskGen(unittest.TestCase):
def test___init___defaults(self):
gen = iaa.SomeColorsMaskGen()
assert np.isclose(gen.nb_bins.a.value, 5)
assert np.isclose(gen.nb_bins.b.value, 15)
assert np.isclose(gen.smoothness.a.value, 0.1)
assert np.isclose(gen.smoothness.b.value, 0.3)
assert np.isclose(gen.alpha.a[0], 0.0)
assert np.isclose(gen.alpha.a[1], 1.0)
assert np.isclose(gen.rotation_deg.a.value, 0)
assert np.isclose(gen.rotation_deg.b.value, 360)
assert gen.from_colorspace == iaa.CSPACE_RGB
def test___init___custom_settings(self):
gen = iaa.SomeColorsMaskGen(
nb_bins=100,
smoothness=0.5,
alpha=0.7,
rotation_deg=123,
from_colorspace=iaa.CSPACE_HSV
)
assert gen.nb_bins.value == 100
assert np.isclose(gen.smoothness.value, 0.5)
assert np.isclose(gen.alpha.value, 0.7)
assert np.isclose(gen.rotation_deg.value, 123)
assert gen.from_colorspace == iaa.CSPACE_HSV
def test_draw_masks_marks_different_colors(self):
image = np.uint8([
[255, 0, 0],
[0, 255, 0],
[0, 0, 255],
[255, 255, 0],
[255, 0, 255],
[0, 255, 255],
[255, 128, 128],
[128, 255, 128],
[128, 128, 255]
]).reshape((9, 1, 3))
image = np.tile(image, (9, 50, 1))
batch = _BatchInAugmentation(images=[image])
gen = iaa.SomeColorsMaskGen(nb_bins=256, smoothness=0,
alpha=[0, 1])
expected_mask_sums = np.arange(1 + image.shape[0]) * image.shape[1]
expected_mask_sums = expected_mask_sums.astype(np.float32)
mask_sums = []
for i in sm.xrange(50):
mask = gen.draw_masks(batch, random_state=i)[0]
mask_sum = int(np.sum(mask))
mask_sums.append(mask_sum)
assert np.any(
np.isclose(
np.min(np.abs(expected_mask_sums - mask_sum)),
0.0,
rtol=0,
atol=0.01)
)
assert mask.shape == image.shape[0:2]
assert mask.dtype.name == "float32"
assert len(np.unique(mask_sums)) >= 4
def test_draw_masks_marks_alpha_is_0(self):
image = np.uint8([
[255, 0, 0],
[0, 255, 0],
[0, 0, 255],
[255, 255, 0],
[255, 0, 255],
[0, 255, 255],
[255, 128, 128],
[128, 255, 128],
[128, 128, 255]
]).reshape((1, 9, 3))
batch = _BatchInAugmentation(images=[image])
gen = iaa.SomeColorsMaskGen(alpha=0.0)
mask = gen.draw_masks(batch)[0]
assert np.allclose(mask, 0.0)
def test_draw_masks_alpha_is_1(self):
image = np.uint8([
[255, 0, 0],
[0, 255, 0],
[0, 0, 255],
[255, 255, 0],
[255, 0, 255],
[0, 255, 255],
[255, 128, 128],
[128, 255, 128],
[128, 128, 255]
]).reshape((1, 9, 3))
batch = _BatchInAugmentation(images=[image])
gen = iaa.SomeColorsMaskGen(alpha=1.0)
mask = gen.draw_masks(batch)[0]
assert np.allclose(mask, 1.0)
@mock.patch("imgaug.augmenters.color.change_colorspace_")
def test_from_colorspace(self, mock_cc):
image = np.uint8([
[255, 0, 0],
[0, 255, 0],
[0, 0, 255],
[255, 255, 0],
[255, 0, 255],
[0, 255, 255],
[255, 128, 128],
[128, 255, 128],
[128, 128, 255]
]).reshape((1, 9, 3))
batch = _BatchInAugmentation(images=[image])
mock_cc.return_value = np.copy(image)
gen = iaa.SomeColorsMaskGen(alpha=1.0, from_colorspace=iaa.CSPACE_BGR)
_ = gen.draw_masks(batch)
assert mock_cc.call_count == 1
assert np.array_equal(mock_cc.call_args_list[0][0][0], image)
assert (mock_cc.call_args_list[0][1]["to_colorspace"]
== iaa.CSPACE_HSV)
assert (mock_cc.call_args_list[0][1]["from_colorspace"]
== iaa.CSPACE_BGR)
def test__upscale_to_256_alpha_bins__1_to_256(self):
alphas = np.float32([0.5])
alphas_up = iaa.SomeColorsMaskGen._upscale_to_256_alpha_bins(alphas)
assert alphas_up.shape == (256,)
assert np.allclose(alphas_up, 0.5)
def test__upscale_to_256_alpha_bins__2_to_256(self):
alphas = np.float32([1.0, 0.5])
alphas_up = iaa.SomeColorsMaskGen._upscale_to_256_alpha_bins(alphas)
assert alphas_up.shape == (256,)
assert np.allclose(alphas_up[0:128], 1.0)
assert np.allclose(alphas_up[128:], 0.5)
def test__upscale_to_256_alpha_bins__255_to_256(self):
alphas = np.zeros((255,), dtype=np.float32)
alphas[0] = 0.25
alphas[1:254] = 0.5
alphas[254] = 1.0
alphas_up = iaa.SomeColorsMaskGen._upscale_to_256_alpha_bins(alphas)
assert alphas_up.shape == (256,)
assert np.allclose(alphas_up[0:2], 0.25)
assert np.allclose(alphas_up[2:], 0.5)
def test__upscale_to_256_alpha_bins__256_to_256(self):
alphas = np.full((256,), 0.5, dtype=np.float32)
alphas_up = iaa.SomeColorsMaskGen._upscale_to_256_alpha_bins(alphas)
assert alphas_up.shape == (256,)
assert np.allclose(alphas, 0.5)
def test__rotate_alpha_bins__by_0(self):
alphas = np.linspace(0.0, 1.0, 256)
alphas_rot = iaa.SomeColorsMaskGen._rotate_alpha_bins(alphas, 0)
assert np.allclose(alphas_rot, alphas)
def test__rotate_alpha_bins__by_1(self):
alphas = np.linspace(0.0, 1.0, 256)
alphas_rot = iaa.SomeColorsMaskGen._rotate_alpha_bins(alphas, 1)
assert np.allclose(alphas_rot[:-1], alphas[1:])
assert np.allclose(alphas_rot[-1:], alphas[:1])
def test__rotate_alpha_bins__by_255(self):
alphas = np.linspace(0.0, 1.0, 256)
alphas_rot = iaa.SomeColorsMaskGen._rotate_alpha_bins(alphas, 255)
assert np.allclose(alphas_rot[:-255], alphas[255:])
assert np.allclose(alphas_rot[-255:], alphas[:255])
def test__rotate_alpha_bins__by_256(self):
alphas = np.linspace(0.0, 1.0, 256)
alphas_rot = iaa.SomeColorsMaskGen._rotate_alpha_bins(alphas, 256)
assert np.allclose(alphas_rot, alphas)
def test__smoothen_alphas__0(self):
alphas = np.zeros((11,), dtype=np.float32)
alphas[5-3:5+3+1] = 1.0
alphas_smooth = iaa.SomeColorsMaskGen._smoothen_alphas(alphas, 0.0)
assert np.allclose(alphas_smooth, alphas)
def test__smoothen_alphas__002(self):
alphas = np.zeros((11,), dtype=np.float32)
alphas[5-3:5+3+1] = 1.0
alphas_smooth = iaa.SomeColorsMaskGen._smoothen_alphas(alphas, 0.02)
assert np.allclose(alphas_smooth, alphas, atol=0.02)
def test__smoothen_alphas__1(self):
alphas = np.zeros((11,), dtype=np.float32)
alphas[5-3:5+3+1] = 1.0
alphas_smooth = iaa.SomeColorsMaskGen._smoothen_alphas(alphas, 1.0)
assert np.isclose(alphas_smooth[0], 0.0, atol=0.01)
assert not np.isclose(alphas_smooth[2], 1.0, atol=0.1)
assert np.isclose(alphas_smooth[5], 1.0, atol=0.01)
def test__generate_pixelwise_alpha_map(self):
image_hsv = np.uint8([
[0, 0, 0],
[50, 0, 0],
[100, 0, 0],
[150, 0, 0],
[200, 0, 0],
[250, 0, 0],
[255, 0, 0]
]).reshape((1, 7, 3))
hue_to_alpha = np.zeros((256,), dtype=np.float32)
hue_to_alpha[0] = 0.1
hue_to_alpha[50] = 0.2
hue_to_alpha[100] = 0.3
hue_to_alpha[150] = 0.4
hue_to_alpha[200] = 0.5
hue_to_alpha[250] = 0.6
hue_to_alpha[255] = 0.7
mask = iaa.SomeColorsMaskGen._generate_pixelwise_alpha_mask(
image_hsv, hue_to_alpha)
# a bit of tolerance here due to the mask being converted from
# [0, 255] to [0.0, 1.0]
assert np.allclose(
mask.flatten(),
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7],
atol=0.05)
def test_zero_sized_axes(self):
shapes = [
(0, 0, 3),
(0, 1, 3),
(1, 0, 3)
]
for shape in shapes:
with self.subTest(shape=shape):
image = np.zeros(shape, dtype=np.uint8)
batch = _BatchInAugmentation(images=[image])
gen = iaa.SomeColorsMaskGen()
mask = gen.draw_masks(batch)[0]
assert mask.shape == shape[0:2]
assert mask.dtype.name == "float32"
def test_batch_contains_no_images(self):
hms = ia.HeatmapsOnImage(np.zeros((5, 5), dtype=np.float32),
shape=(10, 10, 3))
batch = _BatchInAugmentation(heatmaps=[hms])
gen = iaa.SomeColorsMaskGen()
with self.assertRaises(AssertionError):
_masks = gen.draw_masks(batch)
class TestHorizontalLinearGradientMaskGen(unittest.TestCase):
def setUp(self):
reseed()
def test___init__(self):
gen = iaa.HorizontalLinearGradientMaskGen(min_value=0.1,
max_value=1.0,
start_at=0.1,
end_at=0.9)
assert gen.axis == 1
assert np.isclose(gen.min_value.value, 0.1)
assert np.isclose(gen.max_value.value, 1.0)
assert np.isclose(gen.start_at.value, 0.1)
assert np.isclose(gen.end_at.value, 0.9)
def test_draw_masks(self):
image1 = np.zeros((5, 100, 3), dtype=np.uint8)
image2 = np.zeros((7, 200, 3), dtype=np.uint8)
batch = _BatchInAugmentation(images=[image1, image2])
gen = iaa.HorizontalLinearGradientMaskGen(min_value=0.1,
max_value=0.75,
start_at=0.1,
end_at=0.9)
masks = gen.draw_masks(batch, random_state=1)
assert masks[0].shape == image1.shape[0:2]
assert masks[1].shape == image2.shape[0:2]
assert masks[0].dtype.name == "float32"
assert masks[1].dtype.name == "float32"
assert np.allclose(masks[0][:, 0:10], 0.1)
assert np.allclose(masks[1][:, 0:20], 0.1)
assert np.allclose(masks[0][:, 90:], 0.75)
assert np.allclose(masks[1][:, 180:], 0.75)
assert np.allclose(masks[0][:, 10+40], 0.1 + 0.5 * (0.75 - 0.1),
rtol=0, atol=0.05)
assert np.allclose(masks[1][:, 20+80], 0.1 + 0.5 * (0.75 - 0.1),
rtol=0, atol=0.025)
def test_generate_mask__min_value_below_max_value(self):
mask = iaa.HorizontalLinearGradientMaskGen.generate_mask(
(1, 100, 3), min_value=0.75, max_value=0.25,
start_at=0.0, end_at=1.0)
assert mask.shape == (1, 100)
assert np.isclose(mask[0, 0], 0.75)
assert np.isclose(mask[0, -1], 0.25)
assert np.isclose(mask[0, 50], 0.25 + 0.5 * (0.75 - 0.25),
rtol=0, atol=0.05)
def test_generate_mask__end_at_is_before_start_at(self):
mask = iaa.HorizontalLinearGradientMaskGen.generate_mask(
(1, 100, 3), min_value=0.25, max_value=0.75,
start_at=1.0, end_at=0.0)
# like test_generate_mask__min_value_below_max_value(),
# because end < start leads to inversion and we also inverted the
# min and max value above
assert mask.shape == (1, 100)
assert np.isclose(mask[0, 0], 0.75)
assert np.isclose(mask[0, -1], 0.25)
assert np.isclose(mask[0, 50], 0.25 + 0.5 * (0.75 - 0.25),
rtol=0, atol=0.05)
def test_generate_mask__start_at_is_end_at(self):
mask = iaa.HorizontalLinearGradientMaskGen.generate_mask(
(1, 100, 3), min_value=0.0, max_value=1.0,
start_at=0.5, end_at=0.5)
assert mask.shape == (1, 100)
assert np.allclose(mask[:, 0:50], 0.0)
assert np.allclose(mask[:, 50:], 1.0)
def test_generate_mask__min_value_is_max_value(self):
mask = iaa.HorizontalLinearGradientMaskGen.generate_mask(
(1, 100, 3), min_value=0.5, max_value=0.5,
start_at=0.1, end_at=0.8)
assert mask.shape == (1, 100)
assert np.allclose(mask, 0.5)
def test_generate_mask__start_at_and_end_at_are_outside_of_image(self):
mask = iaa.HorizontalLinearGradientMaskGen.generate_mask(
(1, 100, 3), min_value=0.25, max_value=0.75,
start_at=-0.5, end_at=-0.1)
assert mask.shape == (1, 100)
assert np.allclose(mask, 0.75)
def test_zero_sized_axes(self):
shapes = [
(0, 0),
(0, 1),
(1, 0),
(0, 0, 0),
(1, 0, 0),
(0, 1, 0),
(0, 0, 1),
(0, 1, 1),
(1, 0, 1)
]
for shape in shapes:
with self.subTest(shape=shape):
image = np.zeros(shape, dtype=np.uint8)
batch = _BatchInAugmentation(images=[image])
gen = iaa.HorizontalLinearGradientMaskGen()
mask = gen.draw_masks(batch)[0]
assert mask.shape == shape[0:2]
assert mask.dtype.name == "float32"
def test_batch_contains_no_images(self):
hms = ia.HeatmapsOnImage(np.zeros((5, 5), dtype=np.float32),
shape=(10, 10, 3))
batch = _BatchInAugmentation(heatmaps=[hms])
gen = iaa.HorizontalLinearGradientMaskGen(min_value=0.25,
max_value=0.75,
start_at=0.5,
end_at=0.5)
mask = gen.draw_masks(batch)[0]
assert np.allclose(mask[:, 0:5], 0.25)
assert np.allclose(mask[:, 5:], 0.75)
class TestVerticalLinearGradientMaskGen(unittest.TestCase):
def setUp(self):
reseed()
def test___init__(self):
gen = iaa.VerticalLinearGradientMaskGen(min_value=0.1,
max_value=1.0,
start_at=0.1,
end_at=0.9)
assert gen.axis == 0
assert np.isclose(gen.min_value.value, 0.1)
assert np.isclose(gen.max_value.value, 1.0)
assert np.isclose(gen.start_at.value, 0.1)
assert np.isclose(gen.end_at.value, 0.9)
def test_draw_masks(self):
# we transpose the axes in this test, because that way the test is
# essentially identical to the one for HorizontalLinearGradientMaskGen
image1 = np.zeros((5, 100, 3), dtype=np.uint8)
image2 = np.zeros((7, 200, 3), dtype=np.uint8)
image1 = image1.transpose((1, 0, 2))
image2 = image2.transpose((1, 0, 2))
batch = _BatchInAugmentation(images=[image1, image2])
gen = iaa.VerticalLinearGradientMaskGen(min_value=0.1,
max_value=0.75,
start_at=0.1,
end_at=0.9)
masks = gen.draw_masks(batch, random_state=1)
image1 = image1.transpose((1, 0, 2))
image2 = image2.transpose((1, 0, 2))
masks[0] = masks[0].transpose((1, 0))
masks[1] = masks[1].transpose((1, 0))
assert masks[0].shape == image1.shape[0:2]
assert masks[1].shape == image2.shape[0:2]
assert masks[0].dtype.name == "float32"
assert masks[1].dtype.name == "float32"
assert np.allclose(masks[0][:, 0:10], 0.1)
assert np.allclose(masks[1][:, 0:20], 0.1)
assert np.allclose(masks[0][:, 90:], 0.75)
assert np.allclose(masks[1][:, 180:], 0.75)
assert np.allclose(masks[0][:, 10+40], 0.1 + 0.5 * (0.75 - 0.1),
rtol=0, atol=0.05)
assert np.allclose(masks[1][:, 20+80], 0.1 + 0.5 * (0.75 - 0.1),
rtol=0, atol=0.025)
class TestRegularGridMaskGen(unittest.TestCase):
def test___init__(self):
gen = iaa.RegularGridMaskGen(nb_rows=2, nb_cols=[1, 3], alpha=0.6)
assert gen.nb_rows.value == 2
assert gen.nb_cols.a == [1, 3]
assert np.isclose(gen.alpha.value, 0.6)
def test_draw_masks(self):
gen = iaa.RegularGridMaskGen(
nb_rows=2,
nb_cols=iap.DeterministicList([1, 4]),
alpha=iap.DeterministicList([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7,
0.8, 0.9, 1.0]))
image = np.zeros((6, 8, 3), dtype=np.uint8)
batch = _BatchInAugmentation(images=[image, image])
masks = gen.draw_masks(batch, random_state=1)
expected1 = np.full((6, 8), 1.0, dtype=np.float32)
expected1[0:3, :] = 0.1
expected1[3:6, :] = 0.2
expected2 = np.full((6, 8), 1.0, dtype=np.float32)
expected2[0:3, 0:2] = 0.3
expected2[0:3, 2:4] = 0.4
expected2[0:3, 4:6] = 0.5
expected2[0:3, 6:8] = 0.6
expected2[3:6, 0:2] = 0.7
expected2[3:6, 2:4] = 0.8
expected2[3:6, 4:6] = 0.9
expected2[3:6, 6:8] = 1.0
assert np.allclose(masks[0], expected1)
assert np.allclose(masks[1], expected2)
def test_draw_masks__random_alphas(self):
gen = iaa.RegularGridMaskGen(
nb_rows=1,
nb_cols=2,
alpha=[0.1, 0.9])
image = np.zeros((2, 4, 3), dtype=np.uint8)
batch = _BatchInAugmentation(images=[image, image])
expected1 = np.full((2, 4), 0.1, dtype=np.float32)
expected2 = np.full((2, 4), 0.1, dtype=np.float32)
expected3 = np.full((2, 4), 0.1, dtype=np.float32)
expected4 = np.full((2, 4), 0.9, dtype=np.float32)
expected1[:, 0:2] = 0.9
expected2[:, 2:4] = 0.9
seen = [False, False, False, False]
for i in np.arange(50):
masks = gen.draw_masks(batch, random_state=i)
for mask in masks:
if np.allclose(mask, expected1):
seen[0] = True
elif np.allclose(mask, expected2):
seen[1] = True
elif np.allclose(mask, expected3):
seen[2] = True
elif np.allclose(mask, expected4):
seen[3] = True
else:
assert False
if np.all(seen):
break
assert np.all(seen)
def test_generate_mask_rows_1_cols_1(self):
mask = iaa.RegularGridMaskGen.generate_mask(
(5, 7),
nb_rows=1, nb_cols=1,
alphas=np.float32([1, 0]))
assert np.allclose(mask, 1.0)
def test_generate_mask_rows_1_cols_n(self):
mask = iaa.RegularGridMaskGen.generate_mask(
(5, 8),
nb_rows=1, nb_cols=4,
alphas=np.float32([[1, 0, 1, 0]]))
expected = np.full((5, 8), 1.0, dtype=np.float32)
expected[:, 2:4] = 0.0
expected[:, 6:8] = 0.0
assert np.allclose(mask, expected)
def test_generate_mask_rows_n_cols_1(self):
mask = iaa.RegularGridMaskGen.generate_mask(
(8, 5),
nb_rows=4, nb_cols=1,
alphas=np.float32([[1],
[0],
[1],
[0]]))
expected = np.full((8, 5), 1.0, dtype=np.float32)
expected[2:4, :] = 0.0
expected[6:8, :] = 0.0
assert np.allclose(mask, expected)
def test_generate_mask_rows_n_cols_n(self):
mask = iaa.RegularGridMaskGen.generate_mask(
(6, 8),
nb_rows=3, nb_cols=2,
alphas=np.float32([[1, 0],
[0, 1],
[1, 0]]))
expected = np.full((6, 8), 1.0, dtype=np.float32)
expected[0:2, 0:4] = 1.0
expected[0:2, 4:8] = 0.0
expected[2:4, 0:4] = 0.0
expected[2:4, 4:8] = 1.0
expected[4:6, 0:4] = 1.0
expected[4:6, 4:8] = 0.0
assert np.allclose(mask, expected)
def test_generate_mask_with_leftover_pixels(self):
mask = iaa.RegularGridMaskGen.generate_mask(
(15, 15),
nb_rows=4, nb_cols=4,
alphas=np.float32([[1, 0, 1, 0],
[0, 1, 0, 1],
[1, 0, 1, 0],
[0, 1, 0, 1]]))
expected = np.full((12, 12), 0.0, dtype=np.float32)
expected[0:3, 0:3] = 1.0
expected[0:3, 3:6] = 0.0
expected[0:3, 6:9] = 1.0
expected[0:3, 9:12] = 0.0
expected[3:6, 0:3] = 0.0
expected[3:6, 3:6] = 1.0
expected[3:6, 6:9] = 0.0
expected[3:6, 9:12] = 1.0
expected[6:9, 0:3] = 1.0
expected[6:9, 3:6] = 0.0
expected[6:9, 6:9] = 1.0
expected[6:9, 9:12] = 0.0
expected[9:12, 0:3] = 0.0
expected[9:12, 3:6] = 1.0
expected[9:12, 6:9] = 0.0
expected[9:12, 9:12] = 1.0
expected = np.pad(expected, ((1, 2), (1, 2)), mode="reflect")
assert np.allclose(mask, expected)
def test_generate_mask_with_more_columns_than_pixels(self):
mask = iaa.RegularGridMaskGen.generate_mask(
(5, 4),
nb_rows=1, nb_cols=10,
alphas=np.float32([[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]]))
expected = np.full((5, 4), 1.0, dtype=np.float32)
expected[:, 1:2] = 0.0
expected[:, 3:4] = 0.0
assert np.allclose(mask, expected)
def test_generate_mask_with_more_rows_than_pixels(self):
mask = iaa.RegularGridMaskGen.generate_mask(
(4, 5),
nb_rows=6, nb_cols=1,
alphas=np.float32([[1],
[0],
[1],
[0],
[1],
[0]]))
expected = np.full((4, 5), 1.0, dtype=np.float32)
expected[1:2, :] = 0.0
expected[3:4, :] = 0.0
assert np.allclose(mask, expected)
def test_generate_mask__alphas_is_1d_array(self):
mask = iaa.RegularGridMaskGen.generate_mask(
(5, 8),
nb_rows=1, nb_cols=4,
alphas=np.float32([1, 0, 1, 0]))
expected = np.full((5, 8), 1.0, dtype=np.float32)
expected[:, 2:4] = 0.0
expected[:, 6:8] = 0.0
assert np.allclose(mask, expected)
def test_zero_sized_axes(self):
shapes = [
(0, 0),
(0, 1),
(1, 0),
(0, 0, 0),
(1, 0, 0),
(0, 1, 0),
(0, 0, 1),
(0, 1, 1),
(1, 0, 1)
]
for shape in shapes:
with self.subTest(shape=shape):
image = np.zeros(shape, dtype=np.uint8)
batch = _BatchInAugmentation(images=[image])
gen = iaa.RegularGridMaskGen(2, 2)
mask = gen.draw_masks(batch)[0]
assert mask.shape == shape[0:2]
assert mask.dtype.name == "float32"
def test_batch_contains_no_images(self):
hms = ia.HeatmapsOnImage(np.zeros((5, 5), dtype=np.float32),
shape=(6, 8, 3))
batch = _BatchInAugmentation(heatmaps=[hms])
gen = iaa.CheckerboardMaskGen(nb_rows=3, nb_cols=2)
mask = gen.draw_masks(batch, random_state=1)[0]
expected = np.full((6, 8), 1.0, dtype=np.float32)
expected[0:2, 0:4] = 1.0
expected[0:2, 4:8] = 0.0
expected[2:4, 0:4] = 0.0
expected[2:4, 4:8] = 1.0
expected[4:6, 0:4] = 1.0
expected[4:6, 4:8] = 0.0
assert np.allclose(mask, expected)
class TestCheckerboardMaskGen(unittest.TestCase):
def test___init__(self):
gen = iaa.CheckerboardMaskGen(nb_rows=2, nb_cols=[1, 3])
assert gen.nb_rows.value == 2
assert gen.nb_cols.a == [1, 3]
def test_draw_masks(self):
gen = iaa.CheckerboardMaskGen(nb_rows=2,
nb_cols=iap.DeterministicList([1, 4]))
image = np.zeros((6, 8, 3), dtype=np.uint8)
batch = _BatchInAugmentation(images=[image, image])
masks = gen.draw_masks(batch, random_state=1)
expected1 = np.full((6, 8), 1.0, dtype=np.float32)
expected1[3:6, :] = 0.0
expected2 = np.full((6, 8), 1.0, dtype=np.float32)
expected2[0:3, 2:4] = 0.0
expected2[0:3, 6:8] = 0.0
expected2[3:6, 0:2] = 0.0
expected2[3:6, 4:6] = 0.0
assert np.allclose(masks[0], expected1)
assert np.allclose(masks[1], expected2)
def test_generate_mask_rows_1_cols_1(self):
mask = iaa.CheckerboardMaskGen.generate_mask((5, 7),
nb_rows=1, nb_cols=1)
assert np.allclose(mask, 1.0)
def test_generate_mask_rows_1_cols_n(self):
mask = iaa.CheckerboardMaskGen.generate_mask((5, 8),
nb_rows=1, nb_cols=4)
expected = np.full((5, 8), 1.0, dtype=np.float32)
expected[:, 2:4] = 0.0
expected[:, 6:8] = 0.0
assert np.allclose(mask, expected)
def test_generate_mask_rows_n_cols_1(self):
mask = iaa.CheckerboardMaskGen.generate_mask((8, 5),
nb_rows=4, nb_cols=1)
expected = np.full((8, 5), 1.0, dtype=np.float32)
expected[2:4, :] = 0.0
expected[6:8, :] = 0.0
assert np.allclose(mask, expected)
def test_generate_mask_rows_n_cols_n(self):
mask = iaa.CheckerboardMaskGen.generate_mask((6, 8),
nb_rows=3, nb_cols=2)
expected = np.full((6, 8), 1.0, dtype=np.float32)
expected[0:2, 0:4] = 1.0
expected[0:2, 4:8] = 0.0
expected[2:4, 0:4] = 0.0
expected[2:4, 4:8] = 1.0
expected[4:6, 0:4] = 1.0
expected[4:6, 4:8] = 0.0
assert np.allclose(mask, expected)
def test_generate_mask_with_leftover_pixels(self):
mask = iaa.CheckerboardMaskGen.generate_mask((15, 15),
nb_rows=4, nb_cols=4)
expected = np.full((12, 12), 0.0, dtype=np.float32)
expected[0:3, 0:3] = 1.0
expected[0:3, 3:6] = 0.0
expected[0:3, 6:9] = 1.0
expected[0:3, 9:12] = 0.0
expected[3:6, 0:3] = 0.0
expected[3:6, 3:6] = 1.0
expected[3:6, 6:9] = 0.0
expected[3:6, 9:12] = 1.0
expected[6:9, 0:3] = 1.0
expected[6:9, 3:6] = 0.0
expected[6:9, 6:9] = 1.0
expected[6:9, 9:12] = 0.0
expected[9:12, 0:3] = 0.0
expected[9:12, 3:6] = 1.0
expected[9:12, 6:9] = 0.0
expected[9:12, 9:12] = 1.0
expected = np.pad(expected, ((1, 2), (1, 2)), mode="reflect")
assert np.allclose(mask, expected)
def test_generate_mask_with_more_columns_than_pixels(self):
mask = iaa.CheckerboardMaskGen.generate_mask((5, 4),
nb_rows=1, nb_cols=10)
expected = np.full((5, 4), 1.0, dtype=np.float32)
expected[:, 1:2] = 0.0
expected[:, 3:4] = 0.0
assert np.allclose(mask, expected)
def test_generate_mask_with_more_rows_than_pixels(self):
mask = iaa.CheckerboardMaskGen.generate_mask((4, 5),
nb_rows=6, nb_cols=1)
expected = np.full((4, 5), 1.0, dtype=np.float32)
expected[1:2, :] = 0.0
expected[3:4, :] = 0.0
assert np.allclose(mask, expected)
def test_zero_sized_axes(self):
shapes = [
(0, 0),
(0, 1),
(1, 0),
(0, 0, 0),
(1, 0, 0),
(0, 1, 0),
(0, 0, 1),
(0, 1, 1),
(1, 0, 1)
]
for shape in shapes:
with self.subTest(shape=shape):
image = np.zeros(shape, dtype=np.uint8)
batch = _BatchInAugmentation(images=[image])
gen = iaa.CheckerboardMaskGen(2, 2)
mask = gen.draw_masks(batch)[0]
assert mask.shape == shape[0:2]
assert mask.dtype.name == "float32"
def test_batch_contains_no_images(self):
hms = ia.HeatmapsOnImage(np.zeros((5, 5), dtype=np.float32),
shape=(6, 8, 3))
batch = _BatchInAugmentation(heatmaps=[hms])
gen = iaa.CheckerboardMaskGen(nb_rows=3, nb_cols=2)
mask = gen.draw_masks(batch, random_state=1)[0]
expected = np.full((6, 8), 1.0, dtype=np.float32)
expected[0:2, 0:4] = 1.0
expected[0:2, 4:8] = 0.0
expected[2:4, 0:4] = 0.0
expected[2:4, 4:8] = 1.0
expected[4:6, 0:4] = 1.0
expected[4:6, 4:8] = 0.0
assert np.allclose(mask, expected)
class TestSegMapClassIdsMaskGen(unittest.TestCase):
def setUp(self):
reseed()
def test___init___fixed_class_ids_int(self):
gen = iaa.SegMapClassIdsMaskGen(0)
assert gen.class_ids == [0]
assert gen.nb_sample_classes is None
def test___init___fixed_class_ids_list(self):
gen = iaa.SegMapClassIdsMaskGen([0, 1, 3])
assert gen.class_ids == [0, 1, 3]
assert gen.nb_sample_classes is None
def test___init___class_ids_stochastic(self):
gen = iaa.SegMapClassIdsMaskGen([0, 1, 3], nb_sample_classes=2)
assert is_parameter_instance(gen.class_ids, iap.Choice)
assert is_parameter_instance(gen.nb_sample_classes, iap.Deterministic)
def test_draw_masks__fixed_class_ids(self):
segmap_arr = np.zeros((3, 2, 2), dtype=np.int32)
segmap_arr[0, 0, 0] = 1
segmap_arr[0, 1, 0] = 2
segmap_arr[1, 0, 0] = 1
segmap_arr[0, 0, 1] = 3
segmap_arr[1, 1, 1] = 3
segmap = ia.SegmentationMapsOnImage(segmap_arr, shape=(3, 2, 3))
batch = _BatchInAugmentation(segmentation_maps=[segmap])
gen = iaa.SegMapClassIdsMaskGen([2, 3])
mask = gen.draw_masks(batch, random_state=1)[0]
assert mask.shape == segmap_arr.shape[0:2]
assert mask.dtype.name == "float32"
assert np.isclose(mask[0, 0], 1.0) # class id 1 and 3
assert np.isclose(mask[0, 1], 1.0) # class id 2 and 0
assert np.isclose(mask[1, 1], 1.0) # class id 0 and 3
assert np.isclose(mask[1, 0], 0.0) # class id 1 and 0
assert np.allclose(mask[2, :], 0.0) # class id 0 in whole row
def test_draw_masks__stochastic_class_ids(self):
segmap_arr = np.zeros((3, 2, 2), dtype=np.int32)
segmap_arr[0, 0, 0] = 1
segmap_arr[0, 1, 0] = 2
segmap_arr[1, 0, 0] = 1
segmap_arr[0, 0, 1] = 3
segmap_arr[1, 1, 1] = 3
segmap = ia.SegmentationMapsOnImage(segmap_arr, shape=(3, 2, 3))
batch = _BatchInAugmentation(segmentation_maps=[segmap])
gen = iaa.SegMapClassIdsMaskGen([2, 3], nb_sample_classes=1)
expected_class_2 = np.float32([
[0, 1],
[0, 0],
[0, 0]
])
expected_class_3 = np.float32([
[1, 0],
[0, 1],
[0, 0]
])
seen = [False, False]
for i in np.arange(50):
mask = gen.draw_masks(batch, random_state=i)[0]
if np.allclose(mask, expected_class_2):
seen[0] = True
elif np.allclose(mask, expected_class_3):
seen[1] = True
else:
assert False
if np.all(seen):
break
assert np.all(seen)
def test_generate_mask(self):
segmap_arr = np.zeros((3, 2, 2), dtype=np.int32)
segmap_arr[0, 0, 0] = 1
segmap_arr[0, 1, 0] = 2
segmap_arr[1, 0, 0] = 1
segmap_arr[0, 0, 1] = 3
segmap_arr[1, 1, 1] = 3
segmap = ia.SegmentationMapsOnImage(segmap_arr, shape=(3, 2, 3))
mask = iaa.SegMapClassIdsMaskGen.generate_mask(segmap, [1, 2])
expected = np.float32([
[1.0, 1.0],
[1.0, 0.0],
[0.0, 0.0]
])
assert np.allclose(mask, expected)
def test_generate_mask__smaller_than_image(self):
segmap_arr = np.zeros((3, 2, 2), dtype=np.int32)
segmap_arr[0, 0, 0] = 1
segmap_arr[0, 1, 0] = 2
segmap_arr[1, 0, 0] = 1
segmap_arr[0, 0, 1] = 3
segmap_arr[1, 1, 1] = 3
segmap = ia.SegmentationMapsOnImage(segmap_arr, shape=(3, 4))
mask = iaa.SegMapClassIdsMaskGen.generate_mask(segmap, [1, 2])
expected = np.float32([
[1.0, 1.0, 1.0, 1.0],
[1.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0]
])
assert np.allclose(mask, expected, rtol=0.0, atol=0.1)
def test_zero_sized_axes(self):
# zero-sized segmap arrays currently crash when creating
# SegmentationMapsOnImage and that's probably better that way
segmap_shapes = [
(2, 2, 1)
]
image_shapes = [
(2, 3, 3),
(0, 0),
(0, 1),
(1, 0),
(0, 1, 0),
(1, 0, 0),
(0, 1, 1),
(1, 0, 1)
]
for segmap_shape in segmap_shapes:
for image_shape in image_shapes:
with self.subTest(segmap_shape=segmap_shape,
image_shape=image_shape):
segmap_arr = np.zeros(segmap_shape, dtype=np.int32)
segmap = ia.SegmentationMapsOnImage(segmap_arr,
shape=image_shape)
batch = _BatchInAugmentation(segmentation_maps=[segmap])
gen = iaa.SegMapClassIdsMaskGen(1)
mask = gen.draw_masks(batch)[0]
assert mask.shape == image_shape[0:2]
assert mask.dtype.name == "float32"
assert np.allclose(mask, 0.0)
def test_batch_contains_no_segmaps(self):
hms = ia.HeatmapsOnImage(np.zeros((5, 5), dtype=np.float32),
shape=(10, 10, 3))
batch = _BatchInAugmentation(heatmaps=[hms])
gen = iaa.SegMapClassIdsMaskGen(class_ids=[1])
with self.assertRaises(AssertionError):
_mask = gen.draw_masks(batch)[0]
class TestBoundingBoxesMaskGen(unittest.TestCase):
def setUp(self):
reseed()
def test___init___no_labels(self):
gen = iaa.BoundingBoxesMaskGen()
assert gen.labels is None
assert gen.nb_sample_labels is None
def test___init___fixed_labels_single_str(self):
gen = iaa.BoundingBoxesMaskGen("person")
assert gen.labels == ["person"]
assert gen.nb_sample_labels is None
def test___init___fixed_labels_list(self):
gen = iaa.BoundingBoxesMaskGen(["person", "car"])
assert gen.labels == ["person", "car"]
assert gen.nb_sample_labels is None
def test___init___labels_stochastic(self):
gen = iaa.BoundingBoxesMaskGen(["person", "car"], nb_sample_labels=2)
assert is_parameter_instance(gen.labels, iap.Choice)
assert is_parameter_instance(gen.nb_sample_labels, iap.Deterministic)
def test_draw_masks__labels_is_none(self):
bbs = [ia.BoundingBox(x1=1, y1=1, x2=5, y2=5, label="bb1"),
ia.BoundingBox(x1=-3, y1=4, x2=20, y2=8, label="bb2"),
ia.BoundingBox(x1=2, y1=2, x2=10, y2=10, label="bb3")]
bbsoi = ia.BoundingBoxesOnImage(bbs, shape=(10, 14, 3))
batch = _BatchInAugmentation(bounding_boxes=[bbsoi])
gen = iaa.BoundingBoxesMaskGen()
mask = gen.draw_masks(batch, random_state=1)[0]
expected = np.zeros((10, 14), dtype=np.float32)
expected[1:5, 1:5] = 1.0 # bb1
expected[4:8, 0:14] = 1.0 # bb2 clipped to image shape
expected[2:10, 2:10] = 1.0 # bb3
assert mask.shape == (10, 14)
assert mask.dtype.name == "float32"
assert np.allclose(mask, expected)
def test_draw_masks__fixed_labels(self):
bbs = [ia.BoundingBox(x1=1, y1=1, x2=5, y2=5, label="bb1"),
ia.BoundingBox(x1=-3, y1=4, x2=20, y2=8, label="bb2"),
ia.BoundingBox(x1=2, y1=2, x2=10, y2=10, label="bb3")]
bbsoi = ia.BoundingBoxesOnImage(bbs, shape=(10, 14, 3))
batch = _BatchInAugmentation(bounding_boxes=[bbsoi])
gen = iaa.BoundingBoxesMaskGen(["bb1", "bb2"])
mask = gen.draw_masks(batch, random_state=1)[0]
expected = np.zeros((10, 14), dtype=np.float32)
expected[1:5, 1:5] = 1.0 # bb1
expected[4:8, 0:14] = 1.0 # bb2 clipped to image shape
assert mask.shape == (10, 14)
assert mask.dtype.name == "float32"
assert np.allclose(mask, expected)
def test_draw_masks__stochastic_labels(self):
bbs = [ia.BoundingBox(x1=1, y1=1, x2=5, y2=5, label="bb1"),
ia.BoundingBox(x1=-3, y1=4, x2=20, y2=8, label="bb2"),
ia.BoundingBox(x1=2, y1=2, x2=10, y2=10, label="bb3")]
bbsoi = ia.BoundingBoxesOnImage(bbs, shape=(10, 14, 3))
batch = _BatchInAugmentation(bounding_boxes=[bbsoi])
gen = iaa.BoundingBoxesMaskGen(
iap.DeterministicList(["bb1", "bb2"]),
nb_sample_labels=3)
mask = gen.draw_masks(batch, random_state=1)[0]
expected = np.zeros((10, 14), dtype=np.float32)
expected[1:5, 1:5] = 1.0 # bb1
expected[4:8, 0:14] = 1.0 # bb2 clipped to image shape
assert mask.shape == (10, 14)
assert mask.dtype.name == "float32"
assert np.allclose(mask, expected)
def test_generate_mask(self):
bbs = [ia.BoundingBox(x1=1, y1=1, x2=5, y2=5, label="bb1"),
ia.BoundingBox(x1=-3, y1=4, x2=20, y2=8, label="bb2"),
ia.BoundingBox(x1=2, y1=2, x2=10, y2=10, label="bb3")]
bbsoi = ia.BoundingBoxesOnImage(bbs, shape=(10, 14, 3))
mask = iaa.BoundingBoxesMaskGen.generate_mask(bbsoi, ["bb1", "bb2"])
expected = np.zeros((10, 14), dtype=np.float32)
expected[1:5, 1:5] = 1.0 # bb1
expected[4:8, 0:14] = 1.0 # bb2 clipped to image shape
assert mask.shape == (10, 14)
assert mask.dtype.name == "float32"
assert np.allclose(mask, expected)
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):
bbs = [ia.BoundingBox(x1=1, y1=1, x2=5, y2=5, label="bb1"),
ia.BoundingBox(x1=-3, y1=4, x2=20, y2=8, label="bb2"),
ia.BoundingBox(x1=2, y1=2, x2=10, y2=10, label="bb3")]
bbsoi = ia.BoundingBoxesOnImage(bbs, shape=shape)
batch = _BatchInAugmentation(bounding_boxes=[bbsoi])
gen = iaa.BoundingBoxesMaskGen("bb1")
mask = gen.draw_masks(batch)[0]
assert mask.shape == shape[0:2]
assert mask.dtype.name == "float32"
assert np.allclose(mask, 0.0)
def test_batch_contains_no_bounding_boxes(self):
hms = ia.HeatmapsOnImage(np.zeros((5, 5), dtype=np.float32),
shape=(10, 10, 3))
batch = _BatchInAugmentation(heatmaps=[hms])
gen = iaa.SegMapClassIdsMaskGen(class_ids=[1])
with self.assertRaises(AssertionError):
_mask = gen.draw_masks(batch)[0]
class InvertMaskGen(unittest.TestCase):
def setUp(self):
reseed()
def test___init__(self):
child = iaa.HorizontalLinearGradientMaskGen()
gen = iaa.InvertMaskGen(0.5, child)
assert np.isclose(gen.p.p.value, 0.5)
assert gen.child is child
def test_draw_masks(self):
image = np.zeros((1, 20), dtype=np.uint8)
batch = _BatchInAugmentation(images=[image] * 200)
child = iaa.HorizontalLinearGradientMaskGen(min_value=0.0,
max_value=1.0,
start_at=0.0,
end_at=1.0)
gen = iaa.InvertMaskGen(0.5, child)
masks = gen.draw_masks(batch, random_state=1)
hgrad = iaa.HorizontalLinearGradientMaskGen.generate_mask(
(1, 20), min_value=0.0, max_value=1.0, start_at=0.0, end_at=1.0)
expected1 = hgrad
expected2 = 1.0 - hgrad
seen = [0, 0]
for mask in masks:
if np.allclose(mask, expected1):
seen[0] += 1
elif np.allclose(mask, expected2):
seen[1] += 1
else:
assert False
assert np.allclose(seen, 0.5*200, rtol=0, atol=20)
def test_zero_sized_axes(self):
shapes = [
(0, 0),
(0, 1),
(1, 0),
(0, 0, 0),
(1, 0, 0),
(0, 1, 0),
(0, 0, 1),
(0, 1, 1),
(1, 0, 1)
]
for shape in shapes:
with self.subTest(shape=shape):
image = np.zeros(shape, dtype=np.uint8)
batch = _BatchInAugmentation(images=[image])
child = iaa.HorizontalLinearGradientMaskGen()
gen = iaa.InvertMaskGen(0.5, child)
mask = gen.draw_masks(batch)[0]
assert mask.shape == shape[0:2]
assert mask.dtype.name == "float32"
class TestSimplexNoiseAlpha(unittest.TestCase):
def test_deprecation_warning(self):
aug1 = iaa.Sequential([])
aug2 = iaa.Sequential([])
with warnings.catch_warnings(record=True) as caught_warnings:
warnings.simplefilter("always")
aug = iaa.SimplexNoiseAlpha(first=aug1, second=aug2)
assert (
"is deprecated"
in str(caught_warnings[-1].message)
)
assert isinstance(aug, iaa.BlendAlphaSimplexNoise)
assert aug.foreground is aug1
assert aug.background is aug2
class TestFrequencyNoiseAlpha(unittest.TestCase):
def test_deprecation_warning(self):
aug1 = iaa.Sequential([])
aug2 = iaa.Sequential([])
with warnings.catch_warnings(record=True) as caught_warnings:
warnings.simplefilter("always")
aug = iaa.FrequencyNoiseAlpha(first=aug1, second=aug2)
assert (
"is deprecated"
in str(caught_warnings[-1].message)
)
assert isinstance(aug, iaa.BlendAlphaFrequencyNoise)
assert aug.foreground is aug1
assert aug.background is aug2