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)