update
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,45 +0,0 @@
|
||||
import numpy as np
|
||||
import skimage.graph.mcp as mcp
|
||||
|
||||
from skimage._shared.testing import assert_array_equal
|
||||
|
||||
|
||||
a = np.ones((8, 8), dtype=np.float32)
|
||||
|
||||
horizontal_ramp = np.array([[ 0., 1., 2., 3., 4., 5., 6., 7.,],
|
||||
[ 0., 1., 2., 3., 4., 5., 6., 7.,],
|
||||
[ 0., 1., 2., 3., 4., 5., 6., 7.,],
|
||||
[ 0., 1., 2., 3., 4., 5., 6., 7.,],
|
||||
[ 0., 1., 2., 3., 4., 5., 6., 7.,],
|
||||
[ 0., 1., 2., 3., 4., 5., 6., 7.,],
|
||||
[ 0., 1., 2., 3., 4., 5., 6., 7.,],
|
||||
[ 0., 1., 2., 3., 4., 5., 6., 7.,]])
|
||||
|
||||
vertical_ramp = np.array( [[ 0., 0., 0., 0., 0., 0., 0., 0.,],
|
||||
[ 1., 1., 1., 1., 1., 1., 1., 1.,],
|
||||
[ 2., 2., 2., 2., 2., 2., 2., 2.,],
|
||||
[ 3., 3., 3., 3., 3., 3., 3., 3.,],
|
||||
[ 4., 4., 4., 4., 4., 4., 4., 4.,],
|
||||
[ 5., 5., 5., 5., 5., 5., 5., 5.,],
|
||||
[ 6., 6., 6., 6., 6., 6., 6., 6.,],
|
||||
[ 7., 7., 7., 7., 7., 7., 7., 7.,]])
|
||||
|
||||
|
||||
def test_anisotropy():
|
||||
# Create seeds; vertical seeds create a horizonral ramp
|
||||
seeds_for_horizontal = [(i, 0) for i in range(8)]
|
||||
seeds_for_vertcal = [(0, i) for i in range(8)]
|
||||
|
||||
for sy in range(1, 5):
|
||||
for sx in range(1, 5):
|
||||
sampling = sy, sx
|
||||
# Trace horizontally
|
||||
m1 = mcp.MCP_Geometric(a, sampling=sampling, fully_connected=True)
|
||||
costs1, traceback = m1.find_costs(seeds_for_horizontal)
|
||||
# Trace vertically
|
||||
m2 = mcp.MCP_Geometric(a, sampling=sampling, fully_connected=True)
|
||||
costs2, traceback = m2.find_costs(seeds_for_vertcal)
|
||||
|
||||
# Check
|
||||
assert_array_equal(costs1, horizontal_ramp * sx)
|
||||
assert_array_equal(costs2, vertical_ramp * sy)
|
||||
@@ -1,75 +0,0 @@
|
||||
import numpy as np
|
||||
import skimage.graph.mcp as mcp
|
||||
# import stentseg.graph._mcp as mcp
|
||||
|
||||
from skimage._shared.testing import assert_array_equal
|
||||
|
||||
|
||||
a = np.ones((8, 8), dtype=np.float32)
|
||||
count = 0
|
||||
|
||||
|
||||
class MCP(mcp.MCP_Connect):
|
||||
def _reset(self):
|
||||
""" Reset the id map.
|
||||
"""
|
||||
mcp.MCP_Connect._reset(self)
|
||||
self._conn = {}
|
||||
self._bestconn = {}
|
||||
|
||||
def create_connection(self, id1, id2, pos1, pos2, cost1, cost2):
|
||||
# Process data
|
||||
hash = min(id1, id2), max(id1, id2)
|
||||
val = min(pos1, pos2), max(pos1, pos2)
|
||||
cost = min(cost1, cost2)
|
||||
# Add to total list
|
||||
self._conn.setdefault(hash, []).append(val)
|
||||
# Keep track of connection with lowest cost
|
||||
curcost = self._bestconn.get(hash, (np.inf,))[0]
|
||||
if cost < curcost:
|
||||
self._bestconn[hash] = (cost,) + val
|
||||
|
||||
|
||||
def test_connections():
|
||||
# Create MCP object with three seed points
|
||||
mcp = MCP(a)
|
||||
costs, traceback = mcp.find_costs([(1, 1), (7, 7), (1, 7)])
|
||||
|
||||
# Test that all three seed points are connected
|
||||
connections = set(mcp._conn.keys())
|
||||
assert (0, 1) in connections
|
||||
assert (1, 2) in connections
|
||||
assert (0, 2) in connections
|
||||
|
||||
# Test that any two neighbors have only been connected once
|
||||
for position_tuples in mcp._conn.values():
|
||||
n1 = len(position_tuples)
|
||||
n2 = len(set(position_tuples))
|
||||
assert n1 == n2
|
||||
|
||||
# For seed 0 and 1
|
||||
cost, pos1, pos2 = mcp._bestconn[(0, 1)]
|
||||
# Test meeting points
|
||||
assert (pos1, pos2) == ((3, 3), (4, 4))
|
||||
# Test the whole path
|
||||
path = mcp.traceback(pos1) + list(reversed(mcp.traceback(pos2)))
|
||||
assert_array_equal(
|
||||
path, [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7)])
|
||||
|
||||
# For seed 1 and 2
|
||||
cost, pos1, pos2 = mcp._bestconn[(1, 2)]
|
||||
# Test meeting points
|
||||
assert (pos1, pos2) == ((3, 7), (4, 7))
|
||||
# Test the whole path
|
||||
path = mcp.traceback(pos1) + list(reversed(mcp.traceback(pos2)))
|
||||
assert_array_equal(
|
||||
path, [(1, 7), (2, 7), (3, 7), (4, 7), (5, 7), (6, 7), (7, 7)])
|
||||
|
||||
# For seed 0 and 2
|
||||
cost, pos1, pos2 = mcp._bestconn[(0, 2)]
|
||||
# Test meeting points
|
||||
assert (pos1, pos2) == ((1, 3), (1, 4))
|
||||
# Test the whole path
|
||||
path = mcp.traceback(pos1) + list(reversed(mcp.traceback(pos2)))
|
||||
assert_array_equal(
|
||||
path, [(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7)])
|
||||
@@ -1,53 +0,0 @@
|
||||
import numpy as np
|
||||
import skimage.graph.mcp as mcp
|
||||
|
||||
from skimage._shared.testing import assert_array_equal
|
||||
|
||||
|
||||
a = np.ones((8, 8), dtype=np.float32)
|
||||
a[1::2] *= 2.0
|
||||
|
||||
|
||||
class FlexibleMCP(mcp.MCP_Flexible):
|
||||
""" Simple MCP subclass that allows the front to travel
|
||||
a certain distance from the seed point, and uses a constant
|
||||
cost factor that is independent of the cost array.
|
||||
"""
|
||||
|
||||
def _reset(self):
|
||||
mcp.MCP_Flexible._reset(self)
|
||||
self._distance = np.zeros((8, 8), dtype=np.float32).ravel()
|
||||
|
||||
def goal_reached(self, index, cumcost):
|
||||
if self._distance[index] > 4:
|
||||
return 2
|
||||
else:
|
||||
return 0
|
||||
|
||||
def travel_cost(self, index, new_index, offset_length):
|
||||
return 1.0 # fixed cost
|
||||
|
||||
def examine_neighbor(self, index, new_index, offset_length):
|
||||
pass # We do not test this
|
||||
|
||||
def update_node(self, index, new_index, offset_length):
|
||||
self._distance[new_index] = self._distance[index] + 1
|
||||
|
||||
|
||||
def test_flexible():
|
||||
# Create MCP and do a traceback
|
||||
mcp = FlexibleMCP(a)
|
||||
costs, traceback = mcp.find_costs([(0, 0)])
|
||||
|
||||
# Check that inner part is correct. This basically
|
||||
# tests whether travel_cost works.
|
||||
assert_array_equal(costs[:4, :4], [[1, 2, 3, 4],
|
||||
[2, 2, 3, 4],
|
||||
[3, 3, 3, 4],
|
||||
[4, 4, 4, 4]])
|
||||
|
||||
# Test that the algorithm stopped at the right distance.
|
||||
# Note that some of the costs are filled in but not yet frozen,
|
||||
# so we take a bit of margin
|
||||
assert np.all(costs[-2:, :] == np.inf)
|
||||
assert np.all(costs[:, -2:] == np.inf)
|
||||
@@ -1,50 +0,0 @@
|
||||
import time
|
||||
import random
|
||||
import skimage.graph.heap as heap
|
||||
|
||||
from skimage._shared.testing import test_parallel
|
||||
|
||||
|
||||
@test_parallel()
|
||||
def test_heap():
|
||||
_test_heap(100000, True)
|
||||
_test_heap(100000, False)
|
||||
|
||||
|
||||
def _test_heap(n, fast_update):
|
||||
# generate random numbers with duplicates
|
||||
random.seed(0)
|
||||
a = [random.uniform(1.0, 100.0) for i in range(n // 2)]
|
||||
a = a + a
|
||||
|
||||
t0 = time.perf_counter()
|
||||
|
||||
# insert in heap with random removals
|
||||
if fast_update:
|
||||
h = heap.FastUpdateBinaryHeap(128, n)
|
||||
else:
|
||||
h = heap.BinaryHeap(128)
|
||||
for i in range(len(a)):
|
||||
h.push(a[i], i)
|
||||
if a[i] < 25:
|
||||
# double-push same ref sometimes to test fast update codepaths
|
||||
h.push(2 * a[i], i)
|
||||
if 25 < a[i] < 50:
|
||||
# pop some to test random removal
|
||||
h.pop()
|
||||
|
||||
# pop from heap
|
||||
b = []
|
||||
while True:
|
||||
try:
|
||||
b.append(h.pop()[0])
|
||||
except IndexError:
|
||||
break
|
||||
|
||||
t1 = time.perf_counter()
|
||||
|
||||
# verify
|
||||
for i in range(1, len(b)):
|
||||
assert(b[i] >= b[i - 1])
|
||||
|
||||
return t1 - t0
|
||||
@@ -1,163 +0,0 @@
|
||||
import numpy as np
|
||||
import skimage.graph.mcp as mcp
|
||||
|
||||
from skimage._shared.testing import (assert_array_equal, assert_almost_equal,
|
||||
parametrize)
|
||||
from skimage._shared._warnings import expected_warnings
|
||||
|
||||
|
||||
np.random.seed(0)
|
||||
a = np.ones((8, 8), dtype=np.float32)
|
||||
a[1:-1, 1] = 0
|
||||
a[1, 1:-1] = 0
|
||||
|
||||
warning_optional = r'|\A\Z'
|
||||
|
||||
|
||||
def test_basic():
|
||||
with expected_warnings(['Upgrading NumPy' + warning_optional]):
|
||||
m = mcp.MCP(a, fully_connected=True)
|
||||
costs, traceback = m.find_costs([(1, 6)])
|
||||
return_path = m.traceback((7, 2))
|
||||
assert_array_equal(costs,
|
||||
[[1., 1., 1., 1., 1., 1., 1., 1.],
|
||||
[1., 0., 0., 0., 0., 0., 0., 1.],
|
||||
[1., 0., 1., 1., 1., 1., 1., 1.],
|
||||
[1., 0., 1., 2., 2., 2., 2., 2.],
|
||||
[1., 0., 1., 2., 3., 3., 3., 3.],
|
||||
[1., 0., 1., 2., 3., 4., 4., 4.],
|
||||
[1., 0., 1., 2., 3., 4., 5., 5.],
|
||||
[1., 1., 1., 2., 3., 4., 5., 6.]])
|
||||
|
||||
assert_array_equal(return_path,
|
||||
[(1, 6),
|
||||
(1, 5),
|
||||
(1, 4),
|
||||
(1, 3),
|
||||
(1, 2),
|
||||
(2, 1),
|
||||
(3, 1),
|
||||
(4, 1),
|
||||
(5, 1),
|
||||
(6, 1),
|
||||
(7, 2)])
|
||||
|
||||
|
||||
def test_neg_inf():
|
||||
expected_costs = np.where(a == 1, np.inf, 0)
|
||||
expected_path = [(1, 6),
|
||||
(1, 5),
|
||||
(1, 4),
|
||||
(1, 3),
|
||||
(1, 2),
|
||||
(2, 1),
|
||||
(3, 1),
|
||||
(4, 1),
|
||||
(5, 1),
|
||||
(6, 1)]
|
||||
test_neg = np.where(a == 1, -1, 0)
|
||||
test_inf = np.where(a == 1, np.inf, 0)
|
||||
with expected_warnings(['Upgrading NumPy' + warning_optional]):
|
||||
m = mcp.MCP(test_neg, fully_connected=True)
|
||||
costs, traceback = m.find_costs([(1, 6)])
|
||||
return_path = m.traceback((6, 1))
|
||||
assert_array_equal(costs, expected_costs)
|
||||
assert_array_equal(return_path, expected_path)
|
||||
with expected_warnings(['Upgrading NumPy' + warning_optional]):
|
||||
m = mcp.MCP(test_inf, fully_connected=True)
|
||||
costs, traceback = m.find_costs([(1, 6)])
|
||||
return_path = m.traceback((6, 1))
|
||||
assert_array_equal(costs, expected_costs)
|
||||
assert_array_equal(return_path, expected_path)
|
||||
|
||||
|
||||
def test_route():
|
||||
with expected_warnings(['Upgrading NumPy' + warning_optional]):
|
||||
return_path, cost = mcp.route_through_array(a, (1, 6), (7, 2),
|
||||
geometric=True)
|
||||
assert_almost_equal(cost, np.sqrt(2) / 2)
|
||||
assert_array_equal(return_path,
|
||||
[(1, 6),
|
||||
(1, 5),
|
||||
(1, 4),
|
||||
(1, 3),
|
||||
(1, 2),
|
||||
(2, 1),
|
||||
(3, 1),
|
||||
(4, 1),
|
||||
(5, 1),
|
||||
(6, 1),
|
||||
(7, 2)])
|
||||
|
||||
|
||||
def test_no_diagonal():
|
||||
with expected_warnings(['Upgrading NumPy' + warning_optional]):
|
||||
m = mcp.MCP(a, fully_connected=False)
|
||||
costs, traceback = m.find_costs([(1, 6)])
|
||||
return_path = m.traceback((7, 2))
|
||||
assert_array_equal(costs,
|
||||
[[2., 1., 1., 1., 1., 1., 1., 2.],
|
||||
[1., 0., 0., 0., 0., 0., 0., 1.],
|
||||
[1., 0., 1., 1., 1., 1., 1., 2.],
|
||||
[1., 0., 1., 2., 2., 2., 2., 3.],
|
||||
[1., 0., 1., 2., 3., 3., 3., 4.],
|
||||
[1., 0., 1., 2., 3., 4., 4., 5.],
|
||||
[1., 0., 1., 2., 3., 4., 5., 6.],
|
||||
[2., 1., 2., 3., 4., 5., 6., 7.]])
|
||||
assert_array_equal(return_path,
|
||||
[(1, 6),
|
||||
(1, 5),
|
||||
(1, 4),
|
||||
(1, 3),
|
||||
(1, 2),
|
||||
(1, 1),
|
||||
(2, 1),
|
||||
(3, 1),
|
||||
(4, 1),
|
||||
(5, 1),
|
||||
(6, 1),
|
||||
(7, 1),
|
||||
(7, 2)])
|
||||
|
||||
|
||||
def test_offsets():
|
||||
offsets = [(1, i) for i in range(10)] + [(1, -i) for i in range(1, 10)]
|
||||
with expected_warnings(['Upgrading NumPy' + warning_optional]):
|
||||
m = mcp.MCP(a, offsets=offsets)
|
||||
costs, traceback = m.find_costs([(1, 6)])
|
||||
assert_array_equal(traceback,
|
||||
[[-2, -2, -2, -2, -2, -2, -2, -2],
|
||||
[-2, -2, -2, -2, -2, -2, -1, -2],
|
||||
[15, 14, 13, 12, 11, 10, 0, 1],
|
||||
[10, 0, 1, 2, 3, 4, 5, 6],
|
||||
[10, 0, 1, 2, 3, 4, 5, 6],
|
||||
[10, 0, 1, 2, 3, 4, 5, 6],
|
||||
[10, 0, 1, 2, 3, 4, 5, 6],
|
||||
[10, 0, 1, 2, 3, 4, 5, 6]])
|
||||
assert hasattr(m, "offsets")
|
||||
assert_array_equal(offsets, m.offsets)
|
||||
|
||||
|
||||
@parametrize("shape", [(100, 100), (5, 8, 13, 17)] * 5)
|
||||
def test_crashing(shape):
|
||||
_test_random(shape)
|
||||
|
||||
|
||||
def _test_random(shape):
|
||||
# Just tests for crashing -- not for correctness.
|
||||
a = np.random.rand(*shape).astype(np.float32)
|
||||
starts = [[0] * len(shape), [-1] * len(shape),
|
||||
(np.random.rand(len(shape)) * shape).astype(int)]
|
||||
ends = [(np.random.rand(len(shape)) * shape).astype(int)
|
||||
for i in range(4)]
|
||||
with expected_warnings(['Upgrading NumPy' + warning_optional]):
|
||||
m = mcp.MCP(a, fully_connected=True)
|
||||
costs, offsets = m.find_costs(starts)
|
||||
for point in [(np.random.rand(len(shape)) * shape).astype(int)
|
||||
for i in range(4)]:
|
||||
m.traceback(point)
|
||||
m._reset()
|
||||
m.find_costs(starts, ends)
|
||||
for end in ends:
|
||||
m.traceback(end)
|
||||
return a, costs, offsets
|
||||
@@ -1,52 +0,0 @@
|
||||
import numpy as np
|
||||
from skimage.graph._graph import pixel_graph, central_pixel
|
||||
|
||||
mask = np.array([[1, 0, 0], [0, 1, 1], [0, 1, 0]], dtype=bool)
|
||||
image = np.random.default_rng().random(mask.shape)
|
||||
|
||||
|
||||
def test_small_graph():
|
||||
g, n = pixel_graph(mask, connectivity=2)
|
||||
assert g.shape == (4, 4)
|
||||
assert len(g.data) == 8
|
||||
np.testing.assert_allclose(np.unique(g.data), [1, np.sqrt(2)])
|
||||
np.testing.assert_array_equal(n, [0, 4, 5, 7])
|
||||
|
||||
|
||||
def test_central_pixel():
|
||||
g, n = pixel_graph(mask, connectivity=2)
|
||||
px, ds = central_pixel(g, n, shape=mask.shape)
|
||||
np.testing.assert_array_equal(px, (1, 1))
|
||||
s2 = np.sqrt(2)
|
||||
np.testing.assert_allclose(ds, [s2*3 + 2, s2 + 2, s2*2 + 2, s2*2 + 2])
|
||||
|
||||
# test raveled coordinate
|
||||
px, _ = central_pixel(g, n)
|
||||
assert px == 4
|
||||
|
||||
# test no nodes given
|
||||
px, _ = central_pixel(g)
|
||||
assert px == 1
|
||||
|
||||
|
||||
def test_edge_function():
|
||||
def edge_func(values_src, values_dst, distances):
|
||||
return np.abs(values_src - values_dst) + distances
|
||||
|
||||
g, n = pixel_graph(
|
||||
image, mask=mask, connectivity=2, edge_function=edge_func
|
||||
)
|
||||
s2 = np.sqrt(2)
|
||||
np.testing.assert_allclose(g[0, 1], np.abs(image[0, 0] - image[1, 1]) + s2)
|
||||
np.testing.assert_allclose(g[1, 2], np.abs(image[1, 1] - image[1, 2]) + 1)
|
||||
np.testing.assert_array_equal(n, [0, 4, 5, 7])
|
||||
|
||||
|
||||
def test_default_edge_func():
|
||||
g, n = pixel_graph(image, spacing=np.array([0.78, 0.78]))
|
||||
num_edges = len(g.data) // 2 # each edge appears in both directions
|
||||
assert num_edges == 12 # lattice in a (3, 3) grid
|
||||
np.testing.assert_almost_equal(
|
||||
g[0, 1], 0.78 * np.abs(image[0, 0] - image[0, 1])
|
||||
)
|
||||
np.testing.assert_array_equal(n, np.arange(image.size))
|
||||
@@ -1,256 +0,0 @@
|
||||
import pytest
|
||||
from numpy.testing import assert_array_equal
|
||||
import numpy as np
|
||||
from skimage import graph
|
||||
from skimage import segmentation, data
|
||||
from skimage._shared import testing
|
||||
|
||||
|
||||
def max_edge(g, src, dst, n):
|
||||
default = {'weight': -np.inf}
|
||||
w1 = g[n].get(src, default)['weight']
|
||||
w2 = g[n].get(dst, default)['weight']
|
||||
return {'weight': max(w1, w2)}
|
||||
|
||||
|
||||
def test_rag_merge():
|
||||
g = graph.RAG()
|
||||
|
||||
for i in range(5):
|
||||
g.add_node(i, {'labels': [i]})
|
||||
|
||||
g.add_edge(0, 1, {'weight': 10})
|
||||
g.add_edge(1, 2, {'weight': 20})
|
||||
g.add_edge(2, 3, {'weight': 30})
|
||||
g.add_edge(3, 0, {'weight': 40})
|
||||
g.add_edge(0, 2, {'weight': 50})
|
||||
g.add_edge(3, 4, {'weight': 60})
|
||||
|
||||
gc = g.copy()
|
||||
|
||||
# We merge nodes and ensure that the minimum weight is chosen
|
||||
# when there is a conflict.
|
||||
g.merge_nodes(0, 2)
|
||||
assert g.adj[1][2]['weight'] == 10
|
||||
assert g.adj[2][3]['weight'] == 30
|
||||
|
||||
# We specify `max_edge` as `weight_func` as ensure that maximum
|
||||
# weight is chosen in case on conflict
|
||||
gc.merge_nodes(0, 2, weight_func=max_edge)
|
||||
assert gc.adj[1][2]['weight'] == 20
|
||||
assert gc.adj[2][3]['weight'] == 40
|
||||
|
||||
g.merge_nodes(1, 4)
|
||||
g.merge_nodes(2, 3)
|
||||
n = g.merge_nodes(3, 4, in_place=False)
|
||||
assert sorted(g.nodes[n]['labels']) == list(range(5))
|
||||
assert list(g.edges()) == []
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"in_place", [True, False],
|
||||
)
|
||||
def test_rag_merge_gh5360(in_place):
|
||||
# Add another test case covering the gallery example plot_rag.py.
|
||||
# See bug report at gh-5360.
|
||||
g = graph.RAG()
|
||||
g.add_edge(1, 2, weight=10)
|
||||
g.add_edge(2, 3, weight=20)
|
||||
g.add_edge(3, 4, weight=30)
|
||||
g.add_edge(4, 1, weight=40)
|
||||
g.add_edge(1, 3, weight=50)
|
||||
for n in g.nodes():
|
||||
g.nodes[n]['labels'] = [n]
|
||||
gc = g.copy()
|
||||
|
||||
# New node ID is chosen if in_place=False
|
||||
merged_id = 3 if in_place is True else 5
|
||||
|
||||
g.merge_nodes(1, 3, in_place=in_place)
|
||||
assert g.adj[merged_id][2]['weight'] == 10
|
||||
assert g.adj[merged_id][4]['weight'] == 30
|
||||
|
||||
gc.merge_nodes(1, 3, weight_func=max_edge, in_place=in_place)
|
||||
assert gc.adj[merged_id][2]['weight'] == 20
|
||||
assert gc.adj[merged_id][4]['weight'] == 40
|
||||
|
||||
|
||||
def test_threshold_cut():
|
||||
|
||||
img = np.zeros((100, 100, 3), dtype='uint8')
|
||||
img[:50, :50] = 255, 255, 255
|
||||
img[:50, 50:] = 254, 254, 254
|
||||
img[50:, :50] = 2, 2, 2
|
||||
img[50:, 50:] = 1, 1, 1
|
||||
|
||||
labels = np.zeros((100, 100), dtype='uint8')
|
||||
labels[:50, :50] = 0
|
||||
labels[:50, 50:] = 1
|
||||
labels[50:, :50] = 2
|
||||
labels[50:, 50:] = 3
|
||||
|
||||
rag = graph.rag_mean_color(img, labels)
|
||||
new_labels = graph.cut_threshold(labels, rag, 10, in_place=False)
|
||||
# Two labels
|
||||
assert new_labels.max() == 1
|
||||
|
||||
new_labels = graph.cut_threshold(labels, rag, 10)
|
||||
# Two labels
|
||||
assert new_labels.max() == 1
|
||||
|
||||
|
||||
def test_cut_normalized():
|
||||
|
||||
img = np.zeros((100, 100, 3), dtype='uint8')
|
||||
img[:50, :50] = 255, 255, 255
|
||||
img[:50, 50:] = 254, 254, 254
|
||||
img[50:, :50] = 2, 2, 2
|
||||
img[50:, 50:] = 1, 1, 1
|
||||
|
||||
labels = np.zeros((100, 100), dtype='uint8')
|
||||
labels[:50, :50] = 0
|
||||
labels[:50, 50:] = 1
|
||||
labels[50:, :50] = 2
|
||||
labels[50:, 50:] = 3
|
||||
|
||||
rag = graph.rag_mean_color(img, labels, mode='similarity')
|
||||
|
||||
new_labels = graph.cut_normalized(labels, rag, in_place=False)
|
||||
new_labels, _, _ = segmentation.relabel_sequential(new_labels)
|
||||
# Two labels
|
||||
assert new_labels.max() == 1
|
||||
|
||||
new_labels = graph.cut_normalized(labels, rag)
|
||||
new_labels, _, _ = segmentation.relabel_sequential(new_labels)
|
||||
assert new_labels.max() == 1
|
||||
|
||||
|
||||
def test_rag_error():
|
||||
img = np.zeros((10, 10, 3), dtype='uint8')
|
||||
labels = np.zeros((10, 10), dtype='uint8')
|
||||
labels[:5, :] = 0
|
||||
labels[5:, :] = 1
|
||||
with testing.raises(ValueError):
|
||||
graph.rag_mean_color(img, labels,
|
||||
2, 'non existent mode')
|
||||
|
||||
|
||||
def _weight_mean_color(graph, src, dst, n):
|
||||
diff = graph.nodes[dst]['mean color'] - graph.nodes[n]['mean color']
|
||||
diff = np.linalg.norm(diff)
|
||||
return {'weight': diff}
|
||||
|
||||
|
||||
def _pre_merge_mean_color(graph, src, dst):
|
||||
graph.nodes[dst]['total color'] += graph.nodes[src]['total color']
|
||||
graph.nodes[dst]['pixel count'] += graph.nodes[src]['pixel count']
|
||||
graph.nodes[dst]['mean color'] = (graph.nodes[dst]['total color'] /
|
||||
graph.nodes[dst]['pixel count'])
|
||||
|
||||
|
||||
def merge_hierarchical_mean_color(labels, rag, thresh, rag_copy=True,
|
||||
in_place_merge=False):
|
||||
return graph.merge_hierarchical(labels, rag, thresh, rag_copy,
|
||||
in_place_merge, _pre_merge_mean_color,
|
||||
_weight_mean_color)
|
||||
|
||||
|
||||
def test_rag_hierarchical():
|
||||
img = np.zeros((8, 8, 3), dtype='uint8')
|
||||
labels = np.zeros((8, 8), dtype='uint8')
|
||||
|
||||
img[:, :, :] = 31
|
||||
labels[:, :] = 1
|
||||
|
||||
img[0:4, 0:4, :] = 10, 10, 10
|
||||
labels[0:4, 0:4] = 2
|
||||
|
||||
img[4:, 0:4, :] = 20, 20, 20
|
||||
labels[4:, 0:4] = 3
|
||||
|
||||
g = graph.rag_mean_color(img, labels)
|
||||
g2 = g.copy()
|
||||
thresh = 20 # more than 11*sqrt(3) but less than
|
||||
|
||||
result = merge_hierarchical_mean_color(labels, g, thresh)
|
||||
assert(np.all(result[:, :4] == result[0, 0]))
|
||||
assert(np.all(result[:, 4:] == result[-1, -1]))
|
||||
|
||||
result = merge_hierarchical_mean_color(labels, g2, thresh,
|
||||
in_place_merge=True)
|
||||
assert(np.all(result[:, :4] == result[0, 0]))
|
||||
assert(np.all(result[:, 4:] == result[-1, -1]))
|
||||
|
||||
result = graph.cut_threshold(labels, g, thresh)
|
||||
assert np.all(result == result[0, 0])
|
||||
|
||||
|
||||
def test_ncut_stable_subgraph():
|
||||
""" Test to catch an error thrown when subgraph has all equal edges. """
|
||||
|
||||
img = np.zeros((100, 100, 3), dtype='uint8')
|
||||
|
||||
labels = np.zeros((100, 100), dtype='uint8')
|
||||
labels[:50, :50] = 1
|
||||
labels[:50, 50:] = 2
|
||||
|
||||
rag = graph.rag_mean_color(img, labels, mode='similarity')
|
||||
new_labels = graph.cut_normalized(labels, rag, in_place=False)
|
||||
new_labels, _, _ = segmentation.relabel_sequential(new_labels)
|
||||
|
||||
assert new_labels.max() == 0
|
||||
|
||||
|
||||
def test_reproducibility():
|
||||
"""ensure cut_normalized returns the same output for the same input,
|
||||
when specifying random_state
|
||||
"""
|
||||
img = data.coffee()
|
||||
labels1 = segmentation.slic(
|
||||
img, compactness=30, n_segments=400, start_label=0)
|
||||
g = graph.rag_mean_color(img, labels1, mode='similarity')
|
||||
results = [None] * 4
|
||||
for i in range(len(results)):
|
||||
results[i] = graph.cut_normalized(
|
||||
labels1, g, in_place=False, thresh=1e-3, random_state=1234)
|
||||
|
||||
for i in range(len(results) - 1):
|
||||
assert_array_equal(results[i], results[i + 1])
|
||||
|
||||
|
||||
def test_generic_rag_2d():
|
||||
labels = np.array([[1, 2], [3, 4]], dtype=np.uint8)
|
||||
g = graph.RAG(labels)
|
||||
assert g.has_edge(1, 2) and g.has_edge(2, 4) and not g.has_edge(1, 4)
|
||||
h = graph.RAG(labels, connectivity=2)
|
||||
assert h.has_edge(1, 2) and h.has_edge(1, 4) and h.has_edge(2, 3)
|
||||
|
||||
|
||||
def test_generic_rag_3d():
|
||||
labels = np.arange(8, dtype=np.uint8).reshape((2, 2, 2))
|
||||
g = graph.RAG(labels)
|
||||
assert g.has_edge(0, 1) and g.has_edge(1, 3) and not g.has_edge(0, 3)
|
||||
h = graph.RAG(labels, connectivity=2)
|
||||
assert h.has_edge(0, 1) and h.has_edge(0, 3) and not h.has_edge(0, 7)
|
||||
k = graph.RAG(labels, connectivity=3)
|
||||
assert k.has_edge(0, 1) and k.has_edge(1, 2) and k.has_edge(2, 5)
|
||||
|
||||
|
||||
def test_rag_boundary():
|
||||
labels = np.zeros((16, 16), dtype='uint8')
|
||||
edge_map = np.zeros_like(labels, dtype=float)
|
||||
|
||||
edge_map[8, :] = 0.5
|
||||
edge_map[:, 8] = 1.0
|
||||
|
||||
labels[:8, :8] = 1
|
||||
labels[:8, 8:] = 2
|
||||
labels[8:, :8] = 3
|
||||
labels[8:, 8:] = 4
|
||||
|
||||
g = graph.rag_boundary(labels, edge_map, connectivity=1)
|
||||
assert set(g.nodes()) == {1, 2, 3, 4}
|
||||
assert set(g.edges()) == {(1, 2), (1, 3), (2, 4), (3, 4)}
|
||||
assert g[1][3]['weight'] == 0.25
|
||||
assert g[2][4]['weight'] == 0.34375
|
||||
assert g[1][3]['count'] == 16
|
||||
@@ -1,32 +0,0 @@
|
||||
import numpy as np
|
||||
import skimage.graph.spath as spath
|
||||
|
||||
from skimage._shared.testing import assert_equal, assert_array_equal
|
||||
|
||||
|
||||
def test_basic():
|
||||
x = np.array([[1, 1, 3],
|
||||
[0, 2, 0],
|
||||
[4, 3, 1]])
|
||||
path, cost = spath.shortest_path(x)
|
||||
assert_array_equal(path, [0, 0, 1])
|
||||
assert_equal(cost, 1)
|
||||
|
||||
|
||||
def test_reach():
|
||||
x = np.array([[1, 1, 3],
|
||||
[0, 2, 0],
|
||||
[4, 3, 1]])
|
||||
path, cost = spath.shortest_path(x, reach=2)
|
||||
assert_array_equal(path, [0, 0, 2])
|
||||
assert_equal(cost, 0)
|
||||
|
||||
|
||||
def test_non_square():
|
||||
x = np.array([[1, 1, 1, 1, 5, 5, 5],
|
||||
[5, 0, 0, 5, 9, 1, 1],
|
||||
[0, 5, 1, 0, 5, 5, 0],
|
||||
[6, 1, 1, 5, 0, 0, 1]])
|
||||
path, cost = spath.shortest_path(x, reach=2)
|
||||
assert_array_equal(path, [2, 1, 1, 2, 3, 3, 2])
|
||||
assert_equal(cost, 0)
|
||||
Reference in New Issue
Block a user