File: C:/Users/fred/anaconda3/Lib/site-packages/skimage/morphology/tests/test_reconstruction.py
import math
import numpy as np
import pytest
from numpy.testing import assert_array_almost_equal
from skimage._shared.utils import _supported_float_type
from skimage.morphology.grayreconstruct import reconstruction
def test_zeros():
"""Test reconstruction with image and mask of zeros"""
assert_array_almost_equal(reconstruction(np.zeros((5, 7)), np.zeros((5, 7))), 0)
def test_image_equals_mask():
"""Test reconstruction where the image and mask are the same"""
assert_array_almost_equal(reconstruction(np.ones((7, 5)), np.ones((7, 5))), 1)
def test_image_less_than_mask():
"""Test reconstruction where the image is uniform and less than mask"""
image = np.ones((5, 5))
mask = np.ones((5, 5)) * 2
assert_array_almost_equal(reconstruction(image, mask), 1)
def test_one_image_peak():
"""Test reconstruction with one peak pixel"""
image = np.ones((5, 5))
image[2, 2] = 2
mask = np.ones((5, 5)) * 3
assert_array_almost_equal(reconstruction(image, mask), 2)
# minsize chosen to test sizes covering use of 8, 16 and 32-bit integers
# internally
@pytest.mark.parametrize('minsize', [None, 200, 20000, 40000, 80000])
@pytest.mark.parametrize('dtype', [np.uint8, np.float32])
def test_two_image_peaks(minsize, dtype):
"""Test reconstruction with two peak pixels isolated by the mask"""
image = np.array(
[
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 3, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1],
],
dtype=dtype,
)
mask = np.array(
[
[4, 4, 4, 1, 1, 1, 1, 1, 1],
[4, 4, 4, 1, 1, 1, 1, 1, 1],
[4, 4, 4, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 4, 4, 4, 1],
[1, 1, 1, 1, 1, 4, 4, 4, 1],
[1, 1, 1, 1, 1, 4, 4, 4, 1],
],
dtype=dtype,
)
expected = np.array(
[
[2, 2, 2, 1, 1, 1, 1, 1, 1],
[2, 2, 2, 1, 1, 1, 1, 1, 1],
[2, 2, 2, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 3, 3, 3, 1],
[1, 1, 1, 1, 1, 3, 3, 3, 1],
[1, 1, 1, 1, 1, 3, 3, 3, 1],
],
dtype=dtype,
)
if minsize is not None:
# increase data size by tiling (done to test various int types)
nrow = math.ceil(math.sqrt(minsize / image.size))
ncol = math.ceil(minsize / (image.size * nrow))
image = np.tile(image, (nrow, ncol))
mask = np.tile(mask, (nrow, ncol))
expected = np.tile(expected, (nrow, ncol))
out = reconstruction(image, mask)
assert out.dtype == _supported_float_type(mask.dtype)
assert_array_almost_equal(out, expected)
def test_zero_image_one_mask():
"""Test reconstruction with an image of all zeros and a mask that's not"""
result = reconstruction(np.zeros((10, 10)), np.ones((10, 10)))
assert_array_almost_equal(result, 0)
@pytest.mark.parametrize(
'dtype',
[
np.int8,
np.uint8,
np.int16,
np.uint16,
np.int32,
np.uint32,
np.int64,
np.uint64,
np.float16,
np.float32,
np.float64,
],
)
def test_fill_hole(dtype):
"""Test reconstruction by erosion, which should fill holes in mask."""
seed = np.array([0, 8, 8, 8, 8, 8, 8, 8, 8, 0], dtype=dtype)
mask = np.array([0, 3, 6, 2, 1, 1, 1, 4, 2, 0], dtype=dtype)
result = reconstruction(seed, mask, method='erosion')
assert result.dtype == _supported_float_type(mask.dtype)
expected = np.array([0, 3, 6, 4, 4, 4, 4, 4, 2, 0], dtype=dtype)
assert_array_almost_equal(result, expected)
def test_invalid_seed():
seed = np.ones((5, 5))
mask = np.ones((5, 5))
with pytest.raises(ValueError):
reconstruction(seed * 2, mask, method='dilation')
with pytest.raises(ValueError):
reconstruction(seed * 0.5, mask, method='erosion')
def test_invalid_footprint():
seed = np.ones((5, 5))
mask = np.ones((5, 5))
with pytest.raises(ValueError):
reconstruction(seed, mask, footprint=np.ones((4, 4)))
with pytest.raises(ValueError):
reconstruction(seed, mask, footprint=np.ones((3, 4)))
reconstruction(seed, mask, footprint=np.ones((3, 3)))
def test_invalid_method():
seed = np.array([0, 8, 8, 8, 8, 8, 8, 8, 8, 0])
mask = np.array([0, 3, 6, 2, 1, 1, 1, 4, 2, 0])
with pytest.raises(ValueError):
reconstruction(seed, mask, method='foo')
def test_invalid_offset_not_none():
"""Test reconstruction with invalid not None offset parameter"""
image = np.array(
[
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 3, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
]
)
mask = np.array(
[
[4, 4, 4, 1, 1, 1, 1, 1],
[4, 4, 4, 1, 1, 1, 1, 1],
[4, 4, 4, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 4, 4, 4],
[1, 1, 1, 1, 1, 4, 4, 4],
[1, 1, 1, 1, 1, 4, 4, 4],
]
)
with pytest.raises(ValueError):
reconstruction(
image,
mask,
method='dilation',
footprint=np.ones((3, 3)),
offset=np.array([3, 0]),
)
def test_offset_not_none():
"""Test reconstruction with valid offset parameter"""
seed = np.array([0, 3, 6, 2, 1, 1, 1, 4, 2, 0])
mask = np.array([0, 8, 6, 8, 8, 8, 8, 4, 4, 0])
expected = np.array([0, 3, 6, 6, 6, 6, 6, 4, 4, 0])
assert_array_almost_equal(
reconstruction(
seed, mask, method='dilation', footprint=np.ones(3), offset=np.array([0])
),
expected,
)