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

1103 lines
37 KiB
Python

from __future__ import print_function, division, absolute_import
from abc import ABCMeta, abstractproperty, abstractmethod
import sys
# unittest only added in 3.4 self.subTest()
if sys.version_info[0] < 3 or sys.version_info[1] < 4:
import unittest2 as unittest
else:
import unittest
# unittest.mock is not available in 2.7 (though unittest2 might contain it?)
try:
import unittest.mock as mock
except ImportError:
import mock
import numpy as np
import six
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.testutils import (reseed, assert_cbaois_equal,
runtest_pickleable_uint8_img,
is_parameter_instance)
from imgaug.augmentables.heatmaps import HeatmapsOnImage
from imgaug.augmentables.segmaps import SegmentationMapsOnImage
import imgaug.augmenters.flip as fliplib
class TestHorizontalFlip(unittest.TestCase):
def test_returns_fliplr(self):
aug = iaa.HorizontalFlip(0.5)
assert isinstance(aug, iaa.Fliplr)
assert np.allclose(aug.p.p.value, 0.5)
class TestVerticalFlip(unittest.TestCase):
def test_returns_flipud(self):
aug = iaa.VerticalFlip(0.5)
assert isinstance(aug, iaa.Flipud)
assert np.allclose(aug.p.p.value, 0.5)
@six.add_metaclass(ABCMeta)
class _TestFliplrAndFlipudBase(object):
def setUp(self):
reseed()
@property
@abstractproperty
def image(self):
pass
@property
@abstractproperty
def image_flipped(self):
pass
@property
def images(self):
return np.array([self.image])
@property
def images_flipped(self):
return np.array([self.image_flipped])
@property
@abstractproperty
def heatmaps(self):
pass
@property
@abstractproperty
def heatmaps_flipped(self):
pass
@property
@abstractproperty
def segmaps(self):
pass
@property
@abstractproperty
def segmaps_flipped(self):
pass
@property
@abstractproperty
def kpsoi(self):
pass
@property
@abstractproperty
def kpsoi_flipped(self):
pass
@property
@abstractproperty
def psoi(self):
pass
@property
@abstractproperty
def psoi_flipped(self):
pass
@property
@abstractproperty
def lsoi(self):
pass
@property
@abstractproperty
def lsoi_flipped(self):
pass
@property
@abstractproperty
def bbsoi(self):
pass
@property
@abstractproperty
def bbsoi_flipped(self):
pass
@abstractmethod
def create_aug(self, *args, **kwargs):
pass
@abstractmethod
def create_arr(self, value, dtype):
pass
@abstractmethod
def create_arr_flipped(self, value, dtype):
pass
def test_images_p_is_0(self):
aug = self.create_aug(0)
for _ in sm.xrange(3):
observed = aug.augment_images(self.images)
expected = self.images
assert np.array_equal(observed, expected)
def test_images_p_is_0__deterministic(self):
aug = self.create_aug(0).to_deterministic()
for _ in sm.xrange(3):
observed = aug.augment_images(self.images)
expected = self.images
assert np.array_equal(observed, expected)
def test_keypoints_p_is_0(self):
self._test_cbaoi_p_is_0("augment_keypoints", self.kpsoi, False)
def test_keypoints_p_is_0__deterministic(self):
self._test_cbaoi_p_is_0("augment_keypoints", self.kpsoi, True)
def test_polygons_p_is_0(self):
self._test_cbaoi_p_is_0("augment_polygons", self.psoi, False)
def test_polygons_p_is_0__deterministic(self):
self._test_cbaoi_p_is_0("augment_polygons", self.psoi, True)
def test_line_strings_p_is_0(self):
self._test_cbaoi_p_is_0("augment_line_strings", self.lsoi, False)
def test_line_strings_p_is_0__deterministic(self):
self._test_cbaoi_p_is_0("augment_line_strings", self.lsoi, True)
def test_bounding_boxes_p_is_0(self):
self._test_cbaoi_p_is_0("augment_bounding_boxes", self.bbsoi, False)
def test_bounding_boxes_p_is_0__deterministic(self):
self._test_cbaoi_p_is_0("augment_bounding_boxes", self.bbsoi, True)
def _test_cbaoi_p_is_0(self, augf_name, cbaoi, deterministic):
aug = self.create_aug(0)
if deterministic:
aug = aug.to_deterministic()
for _ in sm.xrange(3):
observed = getattr(aug, augf_name)(cbaoi)
assert_cbaois_equal(observed, cbaoi)
def test_heatmaps_p_is_0(self):
aug = self.create_aug(0)
heatmaps = self.heatmaps
observed = aug.augment_heatmaps(heatmaps)
assert observed.shape == heatmaps.shape
assert np.isclose(observed.min_value, heatmaps.min_value,
rtol=0, atol=1e-6)
assert np.isclose(observed.max_value, heatmaps.max_value,
rtol=0, atol=1e-6)
assert np.array_equal(observed.get_arr(), heatmaps.get_arr())
def test_segmaps_p_is_0(self):
aug = self.create_aug(0)
observed = aug.augment_segmentation_maps(self.segmaps)
assert observed.shape == self.segmaps.shape
assert np.array_equal(observed.get_arr(), self.segmaps.get_arr())
def test_images_p_is_1(self):
aug = self.create_aug(1.0)
for _ in sm.xrange(3):
observed = aug.augment_images(self.images)
expected = self.images_flipped
assert np.array_equal(observed, expected)
def test_images_p_is_1__deterministic(self):
aug = self.create_aug(1.0).to_deterministic()
for _ in sm.xrange(3):
observed = aug.augment_images(self.images)
expected = self.images_flipped
assert np.array_equal(observed, expected)
def test_keypoints_p_is_1(self):
self._test_cbaoi_p_is_1(
"augment_keypoints", self.kpsoi, self.kpsoi_flipped, False)
def test_keypoints_p_is_1__deterministic(self):
self._test_cbaoi_p_is_1(
"augment_keypoints", self.kpsoi, self.kpsoi_flipped, True)
def test_polygons_p_is_1(self):
self._test_cbaoi_p_is_1(
"augment_polygons", self.psoi, self.psoi_flipped, False)
def test_polygons_p_is_1__deterministic(self):
self._test_cbaoi_p_is_1(
"augment_polygons", self.psoi, self.psoi_flipped, True)
def test_line_strings_p_is_1(self):
self._test_cbaoi_p_is_1(
"augment_line_strings", self.lsoi, self.lsoi_flipped, False)
def test_line_strings_p_is_1__deterministic(self):
self._test_cbaoi_p_is_1(
"augment_line_strings", self.lsoi, self.lsoi_flipped, True)
def test_bounding_boxes_p_is_1(self):
self._test_cbaoi_p_is_1(
"augment_bounding_boxes", self.bbsoi, self.bbsoi_flipped, False)
def test_bounding_boxes_p_is_1__deterministic(self):
self._test_cbaoi_p_is_1(
"augment_bounding_boxes", self.bbsoi, self.bbsoi_flipped, True)
def _test_cbaoi_p_is_1(self, augf_name, cbaoi, cbaoi_flipped,
deterministic):
aug = self.create_aug(1.0)
if deterministic:
aug = aug.to_deterministic()
for _ in sm.xrange(3):
observed = getattr(aug, augf_name)(cbaoi)
assert_cbaois_equal(observed, cbaoi_flipped)
def test_heatmaps_p_is_1(self):
aug = self.create_aug(1.0)
heatmaps = self.heatmaps
observed = aug.augment_heatmaps(heatmaps)
assert observed.shape == heatmaps.shape
assert np.isclose(observed.min_value, heatmaps.min_value,
rtol=0, atol=1e-6)
assert np.isclose(observed.max_value, heatmaps.max_value,
rtol=0, atol=1e-6)
assert np.array_equal(observed.get_arr(),
self.heatmaps_flipped.get_arr())
def test_segmaps_p_is_1(self):
aug = self.create_aug(1.0)
observed = aug.augment_segmentation_maps(self.segmaps)
assert observed.shape == self.segmaps.shape
assert np.array_equal(observed.get_arr(),
self.segmaps_flipped.get_arr())
def test_images_p_is_050(self):
aug = self.create_aug(0.5)
nb_iterations = 1000
nb_images_flipped = 0
for _ in sm.xrange(nb_iterations):
observed = aug.augment_images(self.images)
if np.array_equal(observed, self.images_flipped):
nb_images_flipped += 1
assert np.isclose(nb_images_flipped/nb_iterations,
0.5, rtol=0, atol=0.1)
def test_images_p_is_050__deterministic(self):
aug = self.create_aug(0.5).to_deterministic()
nb_iterations = 1000
nb_images_flipped_det = 0
for _ in sm.xrange(nb_iterations):
observed = aug.augment_images(self.images)
if np.array_equal(observed, self.images_flipped):
nb_images_flipped_det += 1
assert nb_images_flipped_det in [0, nb_iterations]
def test_keypoints_p_is_050(self):
self._test_cbaoi_p_is_050(
"augment_keypoints", self.kpsoi, self.kpsoi_flipped)
def test_keypoints_p_is_050__deterministic(self):
self._test_cbaoi_p_is_050__deterministic(
"augment_keypoints", self.kpsoi, self.kpsoi_flipped)
def test_polygons_p_is_050(self):
self._test_cbaoi_p_is_050(
"augment_polygons", self.psoi, self.psoi_flipped)
def test_polygons_p_is_050__deterministic(self):
self._test_cbaoi_p_is_050__deterministic(
"augment_polygons", self.psoi, self.psoi_flipped)
def test_line_strings_p_is_050(self):
self._test_cbaoi_p_is_050(
"augment_line_strings", self.lsoi, self.lsoi_flipped)
def test_line_strings_p_is_050__deterministic(self):
self._test_cbaoi_p_is_050__deterministic(
"augment_line_strings", self.lsoi, self.lsoi_flipped)
def test_bounding_boxes_p_is_050(self):
self._test_cbaoi_p_is_050(
"augment_bounding_boxes", self.bbsoi, self.bbsoi_flipped)
def test_bounding_boxes_p_is_050__deterministic(self):
self._test_cbaoi_p_is_050__deterministic(
"augment_bounding_boxes", self.bbsoi, self.bbsoi_flipped)
def _test_cbaoi_p_is_050(self, augf_name, cbaoi, cbaoi_flipped):
aug = self.create_aug(0.5)
nb_iterations = 250
nb_cbaoi_flipped = 0
for _ in sm.xrange(nb_iterations):
observed = getattr(aug, augf_name)(cbaoi)
if np.allclose(observed[0].items[0].coords,
cbaoi_flipped[0].items[0].coords):
nb_cbaoi_flipped += 1
assert np.isclose(nb_cbaoi_flipped/nb_iterations,
0.5, rtol=0, atol=0.2)
def _test_cbaoi_p_is_050__deterministic(self, augf_name, cbaoi,
cbaoi_flipped):
aug = self.create_aug(0.5).to_deterministic()
nb_iterations = 10
nb_cbaoi_flipped = 0
for _ in sm.xrange(nb_iterations):
observed = getattr(aug, augf_name)(cbaoi)
if np.allclose(observed[0].items[0].coords,
cbaoi_flipped[0].items[0].coords):
nb_cbaoi_flipped += 1
assert nb_cbaoi_flipped in [0, nb_iterations]
def test_list_of_images_p_is_050(self):
images_multi = [self.image, self.image]
aug = self.create_aug(0.5)
nb_iterations = 1000
nb_flipped_by_pos = [0] * len(images_multi)
for _ in sm.xrange(nb_iterations):
observed = aug.augment_images(images_multi)
for i in sm.xrange(len(images_multi)):
if np.array_equal(observed[i], self.image_flipped):
nb_flipped_by_pos[i] += 1
assert np.allclose(nb_flipped_by_pos,
500, rtol=0, atol=100)
def test_list_of_images_p_is_050__deterministic(self):
images_multi = [self.image, self.image]
aug = self.create_aug(0.5).to_deterministic()
nb_iterations = 10
nb_flipped_by_pos_det = [0] * len(images_multi)
for _ in sm.xrange(nb_iterations):
observed = aug.augment_images(images_multi)
for i in sm.xrange(len(images_multi)):
if np.array_equal(observed[i], self.image_flipped):
nb_flipped_by_pos_det[i] += 1
for val in nb_flipped_by_pos_det:
assert val in [0, nb_iterations]
def test_images_p_is_stochastic_parameter(self):
aug = self.create_aug(p=iap.Choice([0, 1], p=[0.7, 0.3]))
seen = [0, 0]
for _ in sm.xrange(1000):
observed = aug.augment_image(self.image)
if np.array_equal(observed, self.image):
seen[0] += 1
elif np.array_equal(observed, self.image_flipped):
seen[1] += 1
else:
assert False
assert np.allclose(seen, [700, 300], rtol=0, atol=75)
def test_invalid_datatype_for_p_results_in_failure(self):
with self.assertRaises(Exception):
_ = self.create_aug(p="test")
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),
(0, 2),
(2, 0),
(0, 2, 0),
(2, 0, 0),
(0, 2, 1),
(2, 0, 1)
]
for shape in shapes:
with self.subTest(shape=shape):
image = np.zeros(shape, dtype=np.uint8)
aug = self.create_aug(1.0)
image_aug = aug(image=image)
assert image_aug.shape == image.shape
def test_get_parameters(self):
aug = self.create_aug(p=0.5)
params = aug.get_parameters()
assert is_parameter_instance(params[0], iap.Binomial)
assert is_parameter_instance(params[0].p, iap.Deterministic)
assert 0.5 - 1e-4 < params[0].p.value < 0.5 + 1e-4
def test_other_dtypes_bool(self):
aug = self.create_aug(1.0)
image = self.create_arr(True, bool)
expected = self.create_arr_flipped(True, bool)
image_aug = aug.augment_image(image)
assert image_aug.dtype.type == image.dtype.type
assert np.all(image_aug == expected)
def test_other_dtypes_uint_int(self):
aug = self.create_aug(1.0)
dtypes = ["uint8", "uint16", "uint32", "uint64",
"int8", "int32", "int64"]
for dtype in dtypes:
with self.subTest(dtype=dtype):
min_value, center_value, max_value = \
iadt.get_value_range_of_dtype(dtype)
value = max_value
image = self.create_arr(value, dtype)
expected = self.create_arr_flipped(value, dtype)
image_aug = aug.augment_image(image)
assert image_aug.dtype.name == dtype
assert np.array_equal(image_aug, expected)
def test_other_dtypes_float(self):
aug = self.create_aug(1.0)
try:
f128 = [np.dtype("float128").name]
except TypeError:
f128 = [] # float128 not known by user system
dtypes = ["float16", "float32", "float64"] + f128
values = [5000, 1000**2, 1000**3, 1000**4]
for dtype, value in zip(dtypes, values):
with self.subTest(dtype=dtype):
atol = (1e-9 * value
if dtype != "float16"
else 1e-3 * value)
image = self.create_arr(value, dtype)
expected = self.create_arr_flipped(value, dtype)
image_aug = aug.augment_image(image)
assert image_aug.dtype.name == dtype
assert np.allclose(image_aug, expected, atol=atol)
def test_pickleable(self):
aug = self.create_aug(0.5)
runtest_pickleable_uint8_img(aug, iterations=20)
class TestFliplr(_TestFliplrAndFlipudBase, unittest.TestCase):
def setUp(self):
reseed()
@property
def image(self):
base_img = np.array([[0, 0, 1],
[0, 0, 1],
[0, 1, 1]], dtype=np.uint8)
return base_img[:, :, np.newaxis]
@property
def image_flipped(self):
base_img_flipped = np.array([[1, 0, 0],
[1, 0, 0],
[1, 1, 0]], dtype=np.uint8)
return base_img_flipped[:, :, np.newaxis]
@property
def heatmaps(self):
heatmaps_arr = np.float32([
[0.00, 0.50, 0.75],
[0.00, 0.50, 0.75],
[0.75, 0.75, 0.75],
])
return HeatmapsOnImage(heatmaps_arr, shape=(3, 3, 3))
@property
def heatmaps_flipped(self):
heatmaps_arr = np.float32([
[0.75, 0.50, 0.00],
[0.75, 0.50, 0.00],
[0.75, 0.75, 0.75],
])
return HeatmapsOnImage(heatmaps_arr, shape=(3, 3, 3))
@property
def segmaps(self):
segmaps_arr = np.int32([
[0, 1, 2],
[0, 1, 2],
[2, 2, 2],
])
return SegmentationMapsOnImage(segmaps_arr, shape=(3, 3, 3))
@property
def segmaps_flipped(self):
segmaps_arr = np.int32([
[2, 1, 0],
[2, 1, 0],
[2, 2, 2],
])
return SegmentationMapsOnImage(segmaps_arr, shape=(3, 3, 3))
@property
def kpsoi(self):
kps = [ia.Keypoint(x=0, y=0),
ia.Keypoint(x=1, y=1),
ia.Keypoint(x=2, y=2)]
return [ia.KeypointsOnImage(kps, shape=self.image.shape)]
@property
def kpsoi_flipped(self):
kps = [ia.Keypoint(x=3-0, y=0),
ia.Keypoint(x=3-1, y=1),
ia.Keypoint(x=3-2, y=2)]
return [ia.KeypointsOnImage(kps, shape=self.image.shape)]
@property
def psoi(self):
polygons = [ia.Polygon([(0, 0), (2, 0), (2, 2)])]
return [ia.PolygonsOnImage(polygons, shape=self.image.shape)]
@property
def psoi_flipped(self):
polygons = [ia.Polygon([(3-0, 0), (3-2, 0), (3-2, 2)])]
return [ia.PolygonsOnImage(polygons, shape=self.image.shape)]
@property
def lsoi(self):
ls = [ia.LineString([(0, 0), (2, 0), (2, 2)])]
return [ia.LineStringsOnImage(ls, shape=self.image.shape)]
@property
def lsoi_flipped(self):
ls = [ia.LineString([(3-0, 0), (3-2, 0), (3-2, 2)])]
return [ia.LineStringsOnImage(ls, shape=self.image.shape)]
@property
def bbsoi(self):
bbs = [ia.BoundingBox(x1=0, y1=1, x2=2, y2=3)]
return [ia.BoundingBoxesOnImage(bbs, shape=self.image.shape)]
@property
def bbsoi_flipped(self):
# note that x1 and x2 were inverted (otherwise would be x1>x2)
bbs = [ia.BoundingBox(x1=3-2, y1=1, x2=3-0, y2=3)]
return [ia.BoundingBoxesOnImage(bbs, shape=self.image.shape)]
def create_aug(self, *args, **kwargs):
return iaa.Fliplr(*args, **kwargs)
def create_arr(self, value, dtype):
arr = np.zeros((3, 3), dtype=dtype)
arr[0, 0] = value
return arr
def create_arr_flipped(self, value, dtype):
arr = np.zeros((3, 3), dtype=dtype)
arr[0, 2] = value
return arr
class TestFlipud(_TestFliplrAndFlipudBase, unittest.TestCase):
def setUp(self):
reseed()
@property
def image(self):
base_img = np.array([[0, 0, 1],
[0, 0, 1],
[0, 1, 1]], dtype=np.uint8)
return base_img[:, :, np.newaxis]
@property
def image_flipped(self):
base_img_flipped = np.array([[0, 1, 1],
[0, 0, 1],
[0, 0, 1]], dtype=np.uint8)
return base_img_flipped[:, :, np.newaxis]
@property
def heatmaps(self):
heatmaps_arr = np.float32([
[0.00, 0.50, 0.75],
[0.00, 0.50, 0.75],
[0.75, 0.75, 0.75],
])
return HeatmapsOnImage(heatmaps_arr, shape=(3, 3, 3))
@property
def heatmaps_flipped(self):
heatmaps_arr = np.float32([
[0.75, 0.75, 0.75],
[0.00, 0.50, 0.75],
[0.00, 0.50, 0.75],
])
return HeatmapsOnImage(heatmaps_arr, shape=(3, 3, 3))
@property
def segmaps(self):
segmaps_arr = np.int32([
[0, 1, 2],
[0, 1, 2],
[2, 2, 2],
])
return SegmentationMapsOnImage(segmaps_arr, shape=(3, 3, 3))
@property
def segmaps_flipped(self):
segmaps_arr = np.int32([
[2, 2, 2],
[0, 1, 2],
[0, 1, 2],
])
return SegmentationMapsOnImage(segmaps_arr, shape=(3, 3, 3))
@property
def kpsoi(self):
kps = [ia.Keypoint(x=0, y=0),
ia.Keypoint(x=1, y=1),
ia.Keypoint(x=2, y=2)]
return [ia.KeypointsOnImage(kps, shape=self.image.shape)]
@property
def kpsoi_flipped(self):
kps = [ia.Keypoint(x=0, y=3-0),
ia.Keypoint(x=1, y=3-1),
ia.Keypoint(x=2, y=3-2)]
return [ia.KeypointsOnImage(kps, shape=self.image.shape)]
@property
def psoi(self):
polygons = [ia.Polygon([(0, 0), (2, 0), (2, 2)])]
return [ia.PolygonsOnImage(polygons, shape=self.image.shape)]
@property
def psoi_flipped(self):
polygons = [ia.Polygon([(0, 3-0), (2, 3-0), (2, 3-2)])]
return [ia.PolygonsOnImage(polygons, shape=self.image.shape)]
@property
def lsoi(self):
ls = [ia.LineString([(0, 0), (2, 0), (2, 2)])]
return [ia.LineStringsOnImage(ls, shape=self.image.shape)]
@property
def lsoi_flipped(self):
ls = [ia.LineString([(0, 3-0), (2, 3-0), (2, 3-2)])]
return [ia.LineStringsOnImage(ls, shape=self.image.shape)]
@property
def bbsoi(self):
bbs = [ia.BoundingBox(x1=0, y1=1, x2=2, y2=3)]
return [ia.BoundingBoxesOnImage(bbs, shape=self.image.shape)]
@property
def bbsoi_flipped(self):
# note that y1 and y2 were inverted (otherwise would be y1>y2)
bbs = [ia.BoundingBox(x1=0, y1=3-3, x2=2, y2=3-1)]
return [ia.BoundingBoxesOnImage(bbs, shape=self.image.shape)]
def create_aug(self, *args, **kwargs):
return iaa.Flipud(*args, **kwargs)
def create_arr(self, value, dtype):
arr = np.zeros((3, 3), dtype=dtype)
arr[0, 0] = value
return arr
def create_arr_flipped(self, value, dtype):
arr = np.zeros((3, 3), dtype=dtype)
arr[2, 0] = value
return arr
class Test_fliplr(unittest.TestCase):
def setUp(self):
reseed()
@mock.patch("imgaug.augmenters.flip._fliplr_sliced")
@mock.patch("imgaug.augmenters.flip._fliplr_cv2")
def test__fliplr_cv2_called_mocked(self, mock_cv2, mock_sliced):
for dtype in ["uint8", "uint16", "int8", "int16"]:
mock_cv2.reset_mock()
mock_sliced.reset_mock()
arr = np.zeros((1, 1), dtype=dtype)
_ = fliplib.fliplr(arr)
mock_cv2.assert_called_once_with(arr)
assert mock_sliced.call_count == 0
@mock.patch("imgaug.augmenters.flip._fliplr_sliced")
@mock.patch("imgaug.augmenters.flip._fliplr_cv2")
def test__fliplr_sliced_called_mocked(self, mock_cv2, mock_sliced):
try:
f128 = [np.dtype("float128").name]
except TypeError:
f128 = [] # float128 not known by user system
dtypes = [
"bool",
"uint32", "uint64",
"int32", "int64",
"float16", "float32", "float64"
] + f128
for dtype in dtypes:
mock_cv2.reset_mock()
mock_sliced.reset_mock()
arr = np.zeros((1, 1), dtype=dtype)
_ = fliplib.fliplr(arr)
assert mock_cv2.call_count == 0
mock_sliced.assert_called_once_with(arr)
def test__fliplr_cv2_2d(self):
self._test__fliplr_subfunc_n_channels(fliplib._fliplr_cv2, None)
def test__fliplr_cv2_3d_single_channel(self):
self._test__fliplr_subfunc_n_channels(fliplib._fliplr_cv2, 1)
def test__fliplr_cv2_3d_three_channels(self):
self._test__fliplr_subfunc_n_channels(fliplib._fliplr_cv2, 3)
def test__fliplr_cv2_3d_four_channels(self):
self._test__fliplr_subfunc_n_channels(fliplib._fliplr_cv2, 4)
def test__fliplr_sliced_2d(self):
self._test__fliplr_subfunc_n_channels(fliplib._fliplr_sliced, None)
def test__fliplr_sliced_3d_single_channel(self):
self._test__fliplr_subfunc_n_channels(fliplib._fliplr_sliced, 1)
def test__fliplr_sliced_3d_three_channels(self):
self._test__fliplr_subfunc_n_channels(fliplib._fliplr_sliced, 3)
def test__fliplr_sliced_3d_four_channels(self):
self._test__fliplr_subfunc_n_channels(fliplib._fliplr_sliced, 4)
def test__fliplr_sliced_3d_513_channels(self):
self._test__fliplr_subfunc_n_channels(fliplib._fliplr_sliced, 513)
@classmethod
def _test__fliplr_subfunc_n_channels(cls, func, nb_channels):
arr = np.uint8([
[0, 1, 2, 3],
[4, 5, 6, 7],
[10, 11, 12, 13]
])
if nb_channels is not None:
arr = np.tile(arr[..., np.newaxis], (1, 1, nb_channels))
for c in sm.xrange(nb_channels):
arr[..., c] += c
arr_flipped = func(arr)
expected = np.uint8([
[3, 2, 1, 0],
[7, 6, 5, 4],
[13, 12, 11, 10]
])
if nb_channels is not None:
expected = np.tile(expected[..., np.newaxis], (1, 1, nb_channels))
for c in sm.xrange(nb_channels):
expected[..., c] += c
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == arr.shape
assert np.array_equal(arr_flipped, expected)
def test_zero_height_arr_cv2(self):
arr = np.zeros((0, 4, 1), dtype=np.uint8)
arr_flipped = fliplib._fliplr_cv2(arr)
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == (0, 4, 1)
def test_zero_width_arr_cv2(self):
arr = np.zeros((4, 0, 1), dtype=np.uint8)
arr_flipped = fliplib._fliplr_cv2(arr)
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == (4, 0, 1)
def test_zero_channels_arr_cv2(self):
arr = np.zeros((4, 1, 0), dtype=np.uint8)
arr_flipped = fliplib._fliplr_cv2(arr)
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == (4, 1, 0)
def test_513_channels_arr_cv2(self):
arr = np.zeros((1, 2, 513), dtype=np.uint8)
arr[:, 0, :] = 0
arr[:, 1, :] = 255
arr[0, 0, 0] = 1
arr[0, 1, 0] = 254
arr[0, 0, 512] = 2
arr[0, 1, 512] = 253
arr_flipped = fliplib._fliplr_cv2(arr)
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == (1, 2, 513)
assert arr_flipped[0, 1, 0] == 1
assert arr_flipped[0, 0, 0] == 254
assert arr_flipped[0, 1, 512] == 2
assert arr_flipped[0, 0, 512] == 253
assert np.all(arr_flipped[0, 0, 1:-2] == 255)
assert np.all(arr_flipped[0, 1, 1:-2] == 0)
def test_zero_height_arr_sliced(self):
arr = np.zeros((0, 4, 1), dtype=np.uint8)
arr_flipped = fliplib._fliplr_sliced(arr)
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == (0, 4, 1)
def test_zero_width_arr_sliced(self):
arr = np.zeros((4, 0, 1), dtype=np.uint8)
arr_flipped = fliplib._fliplr_sliced(arr)
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == (4, 0, 1)
def test_zero_channels_arr_sliced(self):
arr = np.zeros((4, 1, 0), dtype=np.uint8)
arr_flipped = fliplib._fliplr_sliced(arr)
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == (4, 1, 0)
def test_513_channels_arr_sliced(self):
arr = np.zeros((1, 2, 513), dtype=np.uint8)
arr[:, 0, :] = 0
arr[:, 1, :] = 255
arr[0, 0, 0] = 1
arr[0, 1, 0] = 254
arr[0, 0, 512] = 2
arr[0, 1, 512] = 253
arr_flipped = fliplib._fliplr_sliced(arr)
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == (1, 2, 513)
assert arr_flipped[0, 1, 0] == 1
assert arr_flipped[0, 0, 0] == 254
assert arr_flipped[0, 1, 512] == 2
assert arr_flipped[0, 0, 512] == 253
assert np.all(arr_flipped[0, 0, 1:-2] == 255)
assert np.all(arr_flipped[0, 1, 1:-2] == 0)
def test_bool_faithful(self):
arr = np.array([[False, False, True]], dtype=bool)
arr_flipped = fliplib.fliplr(arr)
expected = np.array([[True, False, False]], dtype=bool)
assert arr_flipped.dtype.name == "bool"
assert arr_flipped.shape == (1, 3)
assert np.array_equal(arr_flipped, expected)
def test_uint_int_faithful(self):
dts = ["uint8", "uint16", "uint32", "uint64",
"int8", "int16", "int32", "int64"]
for dt in dts:
with self.subTest(dtype=dt):
dt = np.dtype(dt)
minv, center, maxv = iadt.get_value_range_of_dtype(dt)
center = int(center)
arr = np.array([[minv, center, maxv]], dtype=dt)
arr_flipped = fliplib.fliplr(arr)
expected = np.array([[maxv, center, minv]], dtype=dt)
assert arr_flipped.dtype.name == dt.name
assert arr_flipped.shape == (1, 3)
assert np.array_equal(arr_flipped, expected)
def test_float_faithful_to_min_max(self):
try:
f128 = [np.dtype("float128").name]
except TypeError:
f128 = [] # float128 not known by user system
dtypes = ["float16", "float32", "float64"] + f128
for dt in dtypes:
with self.subTest(dtype=dt):
dt = np.dtype(dt)
minv, center, maxv = iadt.get_value_range_of_dtype(dt)
center = int(center)
atol = 1e-4 if dt.name == "float16" else 1e-8
arr = np.array([[minv, center, maxv]], dtype=dt)
arr_flipped = fliplib.fliplr(arr)
expected = np.array([[maxv, center, minv]], dtype=dt)
assert arr_flipped.dtype.name == dt.name
assert arr_flipped.shape == (1, 3)
assert np.allclose(arr_flipped, expected, rtol=0, atol=atol)
def test_float_faithful_to_large_values(self):
try:
f128 = [np.dtype("float128").name]
except TypeError:
f128 = [] # float128 not known by user system
dts = ["float16", "float32", "float64"] + f128
values = [
[0.01, 0.1, 1.0, 10.0**1, 10.0**2], # float16
[0.01, 0.1, 1.0, 10.0**1, 10.0**2, 10.0**4, 10.0**6], # float32
[0.01, 0.1, 1.0, 10.0**1, 10.0**2, 10.0**6, 10.0**10], # float64
[0.01, 0.1, 1.0, 10.0**1, 10.0**2, 10.0**7, 10.0**11], # float128
]
for dt, values_i in zip(dts, values):
for value in values_i:
with self.subTest(dtype=dt, value=value):
dt = np.dtype(dt)
minv, center, maxv = -value, 0.0, value
atol = 1e-4 if dt.name == "float16" else 1e-8
arr = np.array([[minv, center, maxv]], dtype=dt)
arr_flipped = fliplib.fliplr(arr)
expected = np.array([[maxv, center, minv]], dtype=dt)
assert arr_flipped.dtype.name == dt.name
assert arr_flipped.shape == (1, 3)
assert np.allclose(arr_flipped, expected, rtol=0, atol=atol)
class Test_flipud(unittest.TestCase):
def setUp(self):
reseed()
def test__flipud_2d(self):
self._test__flipud_subfunc_n_channels(fliplib.flipud, None)
def test__flipud_3d_single_channel(self):
self._test__flipud_subfunc_n_channels(fliplib.flipud, 1)
def test__flipud_3d_three_channels(self):
self._test__flipud_subfunc_n_channels(fliplib.flipud, 3)
def test__flipud_3d_four_channels(self):
self._test__flipud_subfunc_n_channels(fliplib.flipud, 4)
@classmethod
def _test__flipud_subfunc_n_channels(cls, func, nb_channels):
arr = np.uint8([
[0, 1, 2, 3],
[4, 5, 6, 7],
[10, 11, 12, 13]
])
if nb_channels is not None:
arr = np.tile(arr[..., np.newaxis], (1, 1, nb_channels))
for c in sm.xrange(nb_channels):
arr[..., c] += c
arr_flipped = func(arr)
expected = np.uint8([
[10, 11, 12, 13],
[4, 5, 6, 7],
[0, 1, 2, 3]
])
if nb_channels is not None:
expected = np.tile(expected[..., np.newaxis], (1, 1, nb_channels))
for c in sm.xrange(nb_channels):
expected[..., c] += c
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == arr.shape
assert np.array_equal(arr_flipped, expected)
def test_zero_width_arr(self):
arr = np.zeros((4, 0, 1), dtype=np.uint8)
arr_flipped = fliplib.flipud(arr)
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == (4, 0, 1)
def test_zero_height_arr(self):
arr = np.zeros((0, 4, 1), dtype=np.uint8)
arr_flipped = fliplib.flipud(arr)
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == (0, 4, 1)
def test_zero_channels_arr(self):
arr = np.zeros((4, 1, 0), dtype=np.uint8)
arr_flipped = fliplib.flipud(arr)
assert arr_flipped.dtype.name == "uint8"
assert arr_flipped.shape == (4, 1, 0)
def test_bool_faithful(self):
arr = np.array([[False], [False], [True]], dtype=bool)
arr_flipped = fliplib.flipud(arr)
expected = np.array([[True], [False], [False]], dtype=bool)
assert arr_flipped.dtype.name == "bool"
assert arr_flipped.shape == (3, 1)
assert np.array_equal(arr_flipped, expected)
def test_uint_int_faithful(self):
dts = ["uint8", "uint16", "uint32", "uint64",
"int8", "int16", "int32", "int64"]
for dt in dts:
with self.subTest(dtype=dt):
dt = np.dtype(dt)
minv, center, maxv = iadt.get_value_range_of_dtype(dt)
center = int(center)
arr = np.array([[minv], [center], [maxv]], dtype=dt)
arr_flipped = fliplib.flipud(arr)
expected = np.array([[maxv], [center], [minv]], dtype=dt)
assert arr_flipped.dtype.name == dt.name
assert arr_flipped.shape == (3, 1)
assert np.array_equal(arr_flipped, expected)
def test_float_faithful_to_min_max(self):
try:
f128 = [np.dtype("float128")]
except TypeError:
f128 = [] # float128 not known by user system
dts = ["float16", "float32", "float64"] + f128
for dt in dts:
with self.subTest(dtype=dt):
dt = np.dtype(dt)
minv, center, maxv = iadt.get_value_range_of_dtype(dt)
center = int(center)
atol = 1e-4 if dt.name == "float16" else 1e-8
arr = np.array([[minv], [center], [maxv]], dtype=dt)
arr_flipped = fliplib.flipud(arr)
expected = np.array([[maxv], [center], [minv]], dtype=dt)
assert arr_flipped.dtype.name == dt.name
assert arr_flipped.shape == (3, 1)
assert np.allclose(arr_flipped, expected, rtol=0, atol=atol)
def test_float_faithful_to_large_values(self):
try:
f128 = [np.dtype("float128")]
except TypeError:
f128 = [] # float128 not known by user system
dts = ["float16", "float32", "float64"] + f128
values = [
[0.01, 0.1, 1.0, 10.0**1, 10.0**2], # float16
[0.01, 0.1, 1.0, 10.0**1, 10.0**2, 10.0**4, 10.0**6], # float32
[0.01, 0.1, 1.0, 10.0**1, 10.0**2, 10.0**6, 10.0**10], # float64
[0.01, 0.1, 1.0, 10.0**1, 10.0**2, 10.0**7, 10.0**11], # float128
]
for dt, values_i in zip(dts, values):
for value in values_i:
with self.subTest(dtype=dt, value=value):
dt = np.dtype(dt)
minv, center, maxv = -value, 0.0, value
atol = 1e-4 if dt.name == "float16" else 1e-8
arr = np.array([[minv], [center], [maxv]], dtype=dt)
arr_flipped = fliplib.flipud(arr)
expected = np.array([[maxv], [center], [minv]], dtype=dt)
assert arr_flipped.dtype.name == dt.name
assert arr_flipped.shape == (3, 1)
assert np.allclose(arr_flipped, expected, rtol=0, atol=atol)