Skip to content

Commit

Permalink
Add explicit _offsets_to_raveled_neighbors tests
Browse files Browse the repository at this point in the history
The explicit tests are meant to catch subtle changes in the order of
neigbors with the same connectivity. They were reviewed by constructing
an image of the given shape and filling in the raveled image around the
image center and manual inspection of the result. E.g. with

    image = np.zeros(image_shape)
    image_raveled = image.ravel()
    image_center = tuple(s // 2 for s in image_shape)
    image_center_raveled = np.ravel_multi_index(
        image_center, image_shape
    )
    for i, offset in enumerate(offsets):
        index = image_center_raveled + offset
        assert image_raveled[index] == 0
        image_raveled[index] += i + 1
  • Loading branch information
lagru committed Dec 6, 2019
1 parent d8cace7 commit ff952e9
Showing 1 changed file with 82 additions and 17 deletions.
99 changes: 82 additions & 17 deletions skimage/morphology/tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,49 @@

import pytest
import numpy as np
from numpy.testing import assert_array_equal

from skimage.morphology import _util


class TestOffsetsToRaveledNeighbors:

@pytest.mark.parametrize("shape", [
@pytest.mark.parametrize("image_shape", [
(111,), (33, 44), (22, 55, 11), (6, 5, 4, 3)
])
@pytest.mark.parametrize("order", ["C", "F"])
def test_highest_connectivity(self, shape, order):
def test_highest_connectivity(self, image_shape, order):
"""
Check a scenarios where selem is always of the highest connectivity
Check scenarios where selem is always of the highest connectivity
and all dimensions are > 2.
"""
selem = np.ones((3,) * len(shape))
center = (1,) * len(shape)
selem = np.ones((3,) * len(image_shape), dtype=bool)
center = (1,) * len(image_shape)
offsets = _util._offsets_to_raveled_neighbors(
shape, selem, center, order
image_shape, selem, center, order
)

# Assert only neighbors are present (no center)
# Assert only neighbors are present, center was removed
assert len(offsets) == selem.sum() - 1
assert 0 not in offsets
# Assert uniqueness
assert len(set(offsets)) == offsets.size
# selem of hightest connectivity is symmetric around center
# -> offsets build pairs of with same value but different signs
# offsets form pairs of with same value but different signs
# if selem is symmetric around center
assert all(-x in offsets for x in offsets)

# Construct image whose values are the Manhattan distance to its center
image_center = tuple(s // 2 for s in shape)
grid = np.meshgrid(
*[np.abs(np.arange(s, dtype=np.intp) - c)
for s, c in zip(shape, image_center)],
indexing="ij"
)
image_center = tuple(s // 2 for s in image_shape)
coords = [
np.abs(np.arange(s, dtype=np.intp) - c)
for s, c in zip(image_shape, image_center)
]
grid = np.meshgrid(*coords, indexing="ij")
image = np.sum(grid, axis=0)

image_raveled = image.ravel(order)
image_center_raveled = np.ravel_multi_index(
image_center, shape, order=order
image_center, image_shape, order=order
)

# Sample raveled image around its center
Expand All @@ -56,6 +58,69 @@ def test_highest_connectivity(self, shape, order):
assert np.min(samples) == 1
# Assert that only neighbors where selected
# (highest value == connectivity)
assert np.max(samples) == len(shape)
assert np.max(samples) == len(image_shape)
# Assert that nearest neighbors are selected first
assert list(sorted(samples)) == samples

@pytest.mark.parametrize("image_shape", [
(2,), (2, 2), (2, 1, 2), (2, 2, 1, 2), (0, 2, 1, 2)
])
@pytest.mark.parametrize("order", ["C", "F"])
def test_selem_smaller_image(self, image_shape, order):
"""
Test if a dimension in `selem` is smaller than indicated by
`image_shape`.
"""
selem = np.ones((3,) * len(image_shape), dtype=bool)
center = (1,) * len(image_shape)
offsets = _util._offsets_to_raveled_neighbors(
image_shape, selem, center, order
)

# Assert only neighbors are present, center and duplicates (possible
# for this scenario) where removed
assert len(offsets) <= selem.sum() - 1
assert 0 not in offsets
# Assert uniqueness
assert len(set(offsets)) == offsets.size
# offsets form pairs of with same value but different signs
# if selem is symmetric around center
assert all(-x in offsets for x in offsets)

def test_explicit_0(self):
"""Check reviewed example."""
image_shape = (100, 200, 3)
selem = np.ones((3, 3, 3), dtype=bool)
center = (1, 1, 1)
offsets = _util._offsets_to_raveled_neighbors(
image_shape, selem, center
)

desired = np.array([
3, -600, 1, -1, 600, -3, 4, 2, 603, -2, -4,
-597, 601, -599, -601, -603, 599, 597, 602, -604, 596, -596,
-598, -602, 598, 604
])
assert_array_equal(offsets, desired)

def test_explicit_1(self):
"""Check reviewed example where selem is larger in last dimension."""
image_shape = (10, 9, 8, 3)
selem = np.ones((3, 3, 3, 4), dtype=bool)
center = (1, 1, 1, 1)
offsets = _util._offsets_to_raveled_neighbors(
image_shape, selem, center
)

desired = np.array([
24, 3, 1, -1, -3, -24, -216, 216, -192, 215, -2,
-21, -23, 2, -25, -27, 4, 217, 21, 219, -4, 23,
25, -240, 240, 192, 27, -213, -219, 213, -215, -217, -243,
191, -241, 195, 189, 212, 26, 5, 20, 28, 22, 214,
243, -237, -22, 241, -214, -212, 237, -218, -195, -20, 220,
-193, -191, 218, -189, -28, -26, 193, -239, -220, 239, 196,
221, 242, 236, 238, 194, -244, -188, -238, -211, -196, -194,
-190, -236, -19, 244, 29, 188, -242, 190, -187, 197, -235,
245
])
assert_array_equal(offsets, desired)

0 comments on commit ff952e9

Please sign in to comment.