import math import pytest import numpy as np from skimage import data from skimage.transform import pyramids from skimage._shared import testing from skimage._shared.testing import (assert_array_equal, assert_, assert_equal, assert_almost_equal) image = data.astronaut() image_gray = image[..., 0] def test_pyramid_reduce_rgb(): rows, cols, dim = image.shape out = pyramids.pyramid_reduce(image, downscale=2, multichannel=True) assert_array_equal(out.shape, (rows / 2, cols / 2, dim)) def test_pyramid_reduce_gray(): rows, cols = image_gray.shape out1 = pyramids.pyramid_reduce(image_gray, downscale=2, multichannel=False) assert_array_equal(out1.shape, (rows / 2, cols / 2)) assert_almost_equal(out1.ptp(), 1.0, decimal=2) out2 = pyramids.pyramid_reduce(image_gray, downscale=2, multichannel=False, preserve_range=True) assert_almost_equal(out2.ptp() / image_gray.ptp(), 1.0, decimal=2) def test_pyramid_reduce_nd(): for ndim in [1, 2, 3, 4]: img = np.random.randn(*((8, ) * ndim)) out = pyramids.pyramid_reduce(img, downscale=2, multichannel=False) expected_shape = np.asarray(img.shape) / 2 assert_array_equal(out.shape, expected_shape) def test_pyramid_expand_rgb(): rows, cols, dim = image.shape out = pyramids.pyramid_expand(image, upscale=2, multichannel=True) assert_array_equal(out.shape, (rows * 2, cols * 2, dim)) def test_pyramid_expand_gray(): rows, cols = image_gray.shape out = pyramids.pyramid_expand(image_gray, upscale=2, multichannel=False) assert_array_equal(out.shape, (rows * 2, cols * 2)) def test_pyramid_expand_nd(): for ndim in [1, 2, 3, 4]: img = np.random.randn(*((4, ) * ndim)) out = pyramids.pyramid_expand(img, upscale=2, multichannel=False) expected_shape = np.asarray(img.shape) * 2 assert_array_equal(out.shape, expected_shape) def test_build_gaussian_pyramid_rgb(): rows, cols, dim = image.shape pyramid = pyramids.pyramid_gaussian(image, downscale=2, multichannel=True) for layer, out in enumerate(pyramid): layer_shape = (rows / 2 ** layer, cols / 2 ** layer, dim) assert_array_equal(out.shape, layer_shape) def test_build_gaussian_pyramid_gray(): rows, cols = image_gray.shape pyramid = pyramids.pyramid_gaussian(image_gray, downscale=2, multichannel=False) for layer, out in enumerate(pyramid): layer_shape = (rows / 2 ** layer, cols / 2 ** layer) assert_array_equal(out.shape, layer_shape) def test_build_gaussian_pyramid_nd(): for ndim in [1, 2, 3, 4]: img = np.random.randn(*((8, ) * ndim)) original_shape = np.asarray(img.shape) pyramid = pyramids.pyramid_gaussian(img, downscale=2, multichannel=False) for layer, out in enumerate(pyramid): layer_shape = original_shape / 2 ** layer assert_array_equal(out.shape, layer_shape) def test_build_laplacian_pyramid_rgb(): rows, cols, dim = image.shape pyramid = pyramids.pyramid_laplacian(image, downscale=2, multichannel=True) for layer, out in enumerate(pyramid): layer_shape = (rows / 2 ** layer, cols / 2 ** layer, dim) assert_array_equal(out.shape, layer_shape) def test_build_laplacian_pyramid_nd(): for ndim in [1, 2, 3, 4]: img = np.random.randn(*(16, )*ndim) original_shape = np.asarray(img.shape) pyramid = pyramids.pyramid_laplacian(img, downscale=2, multichannel=False) for layer, out in enumerate(pyramid): print(out.shape) layer_shape = original_shape / 2 ** layer assert_array_equal(out.shape, layer_shape) def test_laplacian_pyramid_max_layers(): for downscale in [2, 3, 5, 7]: img = np.random.randn(32, 8) pyramid = pyramids.pyramid_laplacian(img, downscale=downscale, multichannel=False) max_layer = int(np.ceil(math.log(np.max(img.shape), downscale))) for layer, out in enumerate(pyramid): if layer < max_layer: # should not reach all axes as size 1 prior to final level assert_(np.max(out.shape) > 1) # total number of images is max_layer + 1 assert_equal(max_layer, layer) # final layer should be size 1 on all axes assert_array_equal((out.shape), (1, 1)) def test_check_factor(): with testing.raises(ValueError): pyramids._check_factor(0.99) with testing.raises(ValueError): pyramids._check_factor(- 2) @pytest.mark.parametrize('dtype, expected', zip(['float32', 'float64', 'uint8', 'int64'], ['float32', 'float64', 'float64', 'float64'])) def test_pyramid_gaussian_dtype_support(dtype, expected): img = np.random.randn(32, 8).astype(dtype) pyramid = pyramids.pyramid_gaussian(img) assert np.all([im.dtype == expected for im in pyramid])