mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-16 11:21:25 +08:00
Fixing error in ncut when subgraph as all equal weights (#1538)
This commit is contained in:
@@ -29,6 +29,8 @@ def DW_matrices(graph):
|
||||
W = nx.to_scipy_sparse_matrix(graph, format='csc')
|
||||
entries = W.sum(axis=0)
|
||||
D = sparse.dia_matrix((entries, 0), shape=W.shape).tocsc()
|
||||
#print("D = ",D.todense())
|
||||
#print("W = ",W.todense())
|
||||
return D, W
|
||||
|
||||
|
||||
@@ -65,21 +67,3 @@ def ncut_cost(cut, D, W):
|
||||
assoc_b = D.data[~cut].sum()
|
||||
|
||||
return (cut_cost / assoc_a) + (cut_cost / assoc_b)
|
||||
|
||||
|
||||
def normalize(a):
|
||||
"""Normalize values in an array between `0` and `1`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
a : ndarray
|
||||
The array to be normalized.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The normalized array.
|
||||
"""
|
||||
mi = a.min()
|
||||
mx = a.max()
|
||||
return (a - mi) / (mx - mi)
|
||||
|
||||
@@ -195,10 +195,17 @@ def get_min_ncut(ev, d, w, num_cuts):
|
||||
The value of the minimum ncut.
|
||||
"""
|
||||
mcut = np.inf
|
||||
mn = ev.min()
|
||||
mx = ev.max()
|
||||
|
||||
# If all values in `ev` are equal, the loop does not assign a value to
|
||||
# `min_mask`. This implies that the graph can't be further sub-divided
|
||||
# In this case the bi-partition is the the graph itself and an empty set.
|
||||
min_mask = np.zeros_like(ev, dtype=np.bool)
|
||||
|
||||
# Refer Shi & Malik 2001, Section 3.1.3, Page 892
|
||||
# Perform evenly spaced n-cuts and determine the optimal one.
|
||||
for t in np.linspace(0, 1, num_cuts, endpoint=False):
|
||||
for t in np.linspace(mn, mx, num_cuts, endpoint=False):
|
||||
mask = ev > t
|
||||
cost = _ncut.ncut_cost(mask, d, w)
|
||||
if cost < mcut:
|
||||
@@ -266,7 +273,7 @@ def _ncut_relabel(rag, thresh, num_cuts):
|
||||
# Refer Shi & Malik 2001, Section 3.2.3, Page 893
|
||||
vals, vectors = np.real(vals), np.real(vectors)
|
||||
index2 = _ncut_cy.argmin2(vals)
|
||||
ev = _ncut.normalize(vectors[:, index2])
|
||||
ev = vectors[:, index2]
|
||||
|
||||
cut_mask, mcut = get_min_ncut(ev, d, w, num_cuts)
|
||||
if (mcut < thresh):
|
||||
|
||||
@@ -159,3 +159,23 @@ def test_rag_hierarchical():
|
||||
|
||||
result = graph.cut_threshold(labels, g, thresh)
|
||||
assert np.all(result == result[0, 0])
|
||||
|
||||
|
||||
@skipif(not is_installed('networkx'))
|
||||
def test_ncut_stable_subgraph():
|
||||
""" Test to catch an error thrown when subgraph has all eqal edges. """
|
||||
|
||||
img = np.zeros((100, 100, 3), dtype='uint8')
|
||||
|
||||
labels = np.zeros((100, 100), dtype='uint8')
|
||||
labels[...] = 0
|
||||
labels[:50, :50] = 1
|
||||
labels[:50, 50:] = 2
|
||||
|
||||
rag = graph.rag_mean_color(img, labels, mode='similarity')
|
||||
print(rag.edges(data=True))
|
||||
|
||||
new_labels = graph.cut_normalized(labels, rag, in_place=False)
|
||||
new_labels, _, _ = segmentation.relabel_sequential(new_labels)
|
||||
# Two labels
|
||||
assert new_labels.max() == 0
|
||||
|
||||
Reference in New Issue
Block a user