Coverage for nilearn/_utils/tests/test_segmentation.py: 0%
66 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-20 10:58 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-20 10:58 +0200
1"""
2Testing functions for random walker segmentation from scikit-image 0.11.3.
4Thanks to scikit image.
5"""
7import numpy as np
8import pytest
10from nilearn._utils.segmentation import random_walker
13def test_modes_in_random_walker_spacing(rng):
14 """Smoke test for spacing in random_walker."""
15 img = rng.standard_normal(size=(30, 30, 30))
16 labels = np.zeros_like(img)
17 random_walker(img, labels, beta=90, spacing=(3, 3, 3))
20def test_modes_in_random_walker(rng):
21 img = np.zeros((30, 30, 30)) + 0.1 * rng.standard_normal(size=(30, 30, 30))
22 img[9:21, 9:21, 9:21] = 1
23 img[10:20, 10:20, 10:20] = 0
24 labels = np.zeros_like(img)
25 labels[6, 6, 6] = 1
26 labels[14, 15, 16] = 2
27 # default mode = cg
28 random_walker_cg = random_walker(img, labels, beta=90)
29 assert (random_walker_cg.reshape(img.shape)[6, 6, 6] == 1).all()
30 assert img.shape == random_walker_cg.shape
31 # test `mask` strategy of sub function _mask_edges_weights in laplacian
32 labels[5:25, 26:29, 26:29] = -1
33 random_walker(img, labels, beta=30)
36def test_isolated_pixel(rng):
37 data = rng.random((3, 3))
39 # Build the following labels with an isolated seed
40 # in the bottom-right corner:
41 # array([[ 0., -1., -1.],
42 # [-1., -1., -1.],
43 # [-1., -1., 1.]])
44 labels = -np.ones((3, 3))
45 # Point
46 labels[0, 0] = 0
47 # Make a seed
48 labels[2, 2] = 1
49 # The expected result is:
50 # array([[ 0., -1., -1.],
51 # [-1., -1., -1.],
52 # [-1., -1., 1.]])
53 expected = np.array(
54 [[0.0, -1.0, -1.0], [-1.0, -1.0, -1.0], [-1.0, -1.0, 1.0]]
55 )
56 np.testing.assert_array_equal(expected, random_walker(data, labels))
59def test_isolated_seed(rng):
60 data = rng.random((3, 3))
62 # Build the following labels with an isolated seed
63 # in the bottom-right corner:
64 # array([[ 0., 1., -1.],
65 # [-1., -1., -1.],
66 # [-1., -1., 2.]])
67 labels = -np.ones((3, 3))
68 # Make a seed
69 labels[0, 1] = 1
70 # Point next to the seed
71 labels[0, 0] = 0
72 # Set a seed in the middle, it is surrounded by masked pixels
73 labels[2, 2] = 2
74 # The expected result is:
75 # array([[ 1., 1., -1.],
76 # [-1., -1., -1.],
77 # [-1., -1., -1.]])
78 expected = np.array(
79 [[1.0, 1.0, -1.0], [-1.0, -1.0, -1.0], [-1.0, -1.0, -1.0]]
80 )
81 np.testing.assert_array_equal(expected, random_walker(data, labels))
84def test_trivial_cases():
85 # When all voxels are labeled
86 img = np.ones((10, 10, 10))
87 labels = np.ones((10, 10, 10))
89 # It returns same labels which are provided
90 pass_through = random_walker(img, labels)
91 np.testing.assert_array_equal(pass_through, labels)
93 # When there is no seed
94 # Case 1: only masked pixels
95 labels = -np.ones((10, 10, 10))
96 # It returns the labels
97 np.testing.assert_array_equal(random_walker(img, labels), labels)
99 # Case 2: only unlabeled pixels
100 labels = np.zeros((10, 10, 10))
101 # It return the labels
102 np.testing.assert_array_equal(random_walker(img, labels), labels)
105def test_bad_inputs(rng):
106 # Too few dimensions
107 img = np.ones(10)
108 labels = np.arange(10)
109 with pytest.raises(ValueError):
110 random_walker(img, labels)
112 # Too many dimensions
113 img = rng.normal(size=(3, 3, 3, 3, 3))
114 labels = np.arange(3**5).reshape(img.shape)
115 with pytest.raises(ValueError):
116 random_walker(img, labels)
118 # Spacing incorrect length
119 img = rng.normal(size=(10, 10))
120 labels = np.zeros((10, 10))
121 labels[2, 4] = 2
122 labels[6, 8] = 5
123 with pytest.raises(ValueError):
124 random_walker(img, labels, spacing=(1,))
127def test_reorder_labels(rng):
128 """When labels have non-consecutive integers, make them consecutive by \
129 reordering them to make no gaps/differences between integers.
131 We expect labels to be of same shape even if they are reordered.
133 Issue #938, comment #14.
134 """
135 data = np.zeros((5, 5)) + 0.1 * rng.standard_normal(size=(5, 5))
136 data[1:5, 1:5] = 1
138 labels = np.zeros_like(data)
139 labels[3, 3] = 1
140 labels[1, 4] = 4 # giving integer which is non-consecutive
142 labels = random_walker(data, labels)
143 assert data.shape == labels.shape