From 23c6111ad321fc022c1bb6219ba32a75cf0885e4 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 3 Jun 2015 21:58:26 +0530 Subject: [PATCH 1/4] Fixing error in ncut when subgraph as all equal weights (#1538) --- skimage/future/graph/_ncut.py | 20 ++------------------ skimage/future/graph/graph_cut.py | 11 +++++++++-- skimage/future/graph/tests/test_rag.py | 20 ++++++++++++++++++++ 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/skimage/future/graph/_ncut.py b/skimage/future/graph/_ncut.py index 05be8cd1..e18e9595 100644 --- a/skimage/future/graph/_ncut.py +++ b/skimage/future/graph/_ncut.py @@ -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) diff --git a/skimage/future/graph/graph_cut.py b/skimage/future/graph/graph_cut.py index d727eeac..6a4ba03e 100644 --- a/skimage/future/graph/graph_cut.py +++ b/skimage/future/graph/graph_cut.py @@ -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): diff --git a/skimage/future/graph/tests/test_rag.py b/skimage/future/graph/tests/test_rag.py index 1cac2b2d..3c5d12b1 100644 --- a/skimage/future/graph/tests/test_rag.py +++ b/skimage/future/graph/tests/test_rag.py @@ -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 From 18b190660755b129f30bb867fb8061f6912358d9 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 3 Jun 2015 22:03:34 +0530 Subject: [PATCH 2/4] removed debug statements --- skimage/future/graph/_ncut.py | 3 +-- skimage/future/graph/tests/test_rag.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/skimage/future/graph/_ncut.py b/skimage/future/graph/_ncut.py index e18e9595..acdade69 100644 --- a/skimage/future/graph/_ncut.py +++ b/skimage/future/graph/_ncut.py @@ -29,8 +29,7 @@ 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 diff --git a/skimage/future/graph/tests/test_rag.py b/skimage/future/graph/tests/test_rag.py index 3c5d12b1..95611ab9 100644 --- a/skimage/future/graph/tests/test_rag.py +++ b/skimage/future/graph/tests/test_rag.py @@ -173,9 +173,8 @@ def test_ncut_stable_subgraph(): 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 From 8a78ad87ed712e4f62db2cca78f0471e077128bf Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Sat, 6 Jun 2015 00:51:30 +0530 Subject: [PATCH 3/4] skip loop when min and max are equal --- skimage/future/graph/graph_cut.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/skimage/future/graph/graph_cut.py b/skimage/future/graph/graph_cut.py index 6a4ba03e..3b112b7e 100644 --- a/skimage/future/graph/graph_cut.py +++ b/skimage/future/graph/graph_cut.py @@ -198,10 +198,12 @@ def get_min_ncut(ev, d, w, num_cuts): 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. + # If all values in `ev` are equal, it 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) + if np.allclose(mn, mx): + return min_mask, mcut # Refer Shi & Malik 2001, Section 3.1.3, Page 892 # Perform evenly spaced n-cuts and determine the optimal one. From cacd214d688ac872908be13f7f87a58f9b096883 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Sat, 6 Jun 2015 21:36:00 +0530 Subject: [PATCH 4/4] Corrected Typo --- skimage/future/graph/tests/test_rag.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/future/graph/tests/test_rag.py b/skimage/future/graph/tests/test_rag.py index 95611ab9..35c22218 100644 --- a/skimage/future/graph/tests/test_rag.py +++ b/skimage/future/graph/tests/test_rag.py @@ -163,7 +163,7 @@ def test_rag_hierarchical(): @skipif(not is_installed('networkx')) def test_ncut_stable_subgraph(): - """ Test to catch an error thrown when subgraph has all eqal edges. """ + """ Test to catch an error thrown when subgraph has all equal edges. """ img = np.zeros((100, 100, 3), dtype='uint8')