From 1769cdddcffb7c9d9e26600392eeac5252a4bd37 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 6 May 2015 00:47:31 +0530 Subject: [PATCH 01/18] added boundary rag construction --- doc/examples/plot_rag_boundary.py | 28 ++++++++++ skimage/future/graph/__init__.py | 3 +- skimage/future/graph/rag.py | 73 ++++++++++++++++++++++++++ skimage/future/graph/tests/test_rag.py | 17 ++++++ 4 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 doc/examples/plot_rag_boundary.py diff --git a/doc/examples/plot_rag_boundary.py b/doc/examples/plot_rag_boundary.py new file mode 100644 index 00000000..eeff1589 --- /dev/null +++ b/doc/examples/plot_rag_boundary.py @@ -0,0 +1,28 @@ +""" +========================== +Region Boundary based RAGs +========================== + +This example demonstrates construction of region boundary based RAGs with the +`rag_boundary` function. +""" +from skimage.future import graph +from skimage import data, segmentation, color, filters, io +from matplotlib import pyplot as plt, colors + +img = data.coffee() +gimg = color.rgb2gray(img) + +labels = segmentation.slic(img, compactness=30, n_segments=400) +edges = filters.sobel(gimg) +edges_rgb = color.gray2rgb(edges) + +mimg = segmentation.mark_boundaries(img, labels, (0,0,0)) + +g = graph.rag_boundary(labels, edges) + +cmap = colors.ListedColormap(['#0000ff', '#ff0000']) +out = graph.draw_rag(labels, g, edges_rgb, node_color="#ffff00", colormap=cmap) + +io.imshow(out) +io.show() diff --git a/skimage/future/graph/__init__.py b/skimage/future/graph/__init__.py index 6b7e0aaa..e73c8d19 100644 --- a/skimage/future/graph/__init__.py +++ b/skimage/future/graph/__init__.py @@ -1,5 +1,5 @@ from .graph_cut import cut_threshold, cut_normalized -from .rag import rag_mean_color, RAG, draw_rag +from .rag import rag_mean_color, RAG, draw_rag, rag_boundary from .graph_merge import merge_hierarchical ncut = cut_normalized @@ -9,4 +9,5 @@ __all__ = ['rag_mean_color', 'ncut', 'draw_rag', 'merge_hierarchical', + 'rag_boundary' 'RAG'] diff --git a/skimage/future/graph/rag.py b/skimage/future/graph/rag.py index 6a45447b..6c8fa502 100644 --- a/skimage/future/graph/rag.py +++ b/skimage/future/graph/rag.py @@ -311,6 +311,79 @@ def rag_mean_color(image, labels, connectivity=2, mode='distance', return graph +def rag_boundary(labels, edge_map, connectivity=2): + """ Comouter RAG based on region boundaries + + Given an image's initial segmentation and its edge map this method + constructs the corresponding Region Adjacency Graph (RAG). Each node in the + RAG represents a set of pixels within the image with the same label in + `labels`. The weight between two adjacent regions is the average value + in `edge_map` along their boundary. + + labels : ndarray + The labelled image. + edge_map : ndarray + This should have the same shape as that of `labels`. For all pixels + along the boundary between 2 adjacent regions, the average value of the + corresponding pixels in `edge_map` is the edge weight between them. + connectivity : int, optional + Pixels with a squared distance less than `connectivity` from each other + are considered adjacent. It can range from 1 to `labels.ndim`. Its + behavior is the same as `connectivity` parameter in + `scipy.ndimage.filters.generate_binary_structure`. + + Examples + -------- + >>> from skimage import data, segmentation, filters, color + >>> from skimage.future import graph + >>> img = data.chelsea() + >>> labels = segmentation.slic(img) + >>> edge_map = filters.sobel(color.rgb2gray(img)) + >>> rag = graph.rag_mean_color(labels, edge_map) + + """ + + graph = RAG() + + #Computing the relative indices of the neighbors + nbr_indices = list(np.ndindex(*[2]*labels.ndim)) + del nbr_indices[0] + nbr_indices_arr = ([idx for idx in nbr_indices if np.linalg.norm(idx) + <= connectivity]) + + + iter_shape = tuple(np.array(labels.shape) - 1) + + for index in np.ndindex(iter_shape): + + index_arr = np.array(index) + current = labels[index] + graph.add_node(current, {'labels':[current]}) + + for nbr_index in nbr_indices_arr: + + adjacent_idx = tuple(index_arr + nbr_index) + adjacent = labels[adjacent_idx] + + if current==adjacent: + continue + + if graph.has_edge(current, adjacent): + graph[current][adjacent]['pixel count'] += 2 + intensity = edge_map[index] + edge_map[adjacent_idx] + graph[current][adjacent]['total intensity'] += intensity + else: + graph.add_edge(current, adjacent) + graph[current][adjacent]['pixel count'] = 2 + intensity = edge_map[index] + edge_map[adjacent_idx] + graph[current][adjacent]['total intensity'] = intensity + + for (x, y, data) in graph.edges_iter(data=True): + data['weight'] = data['total intensity']/data['pixel count'] + + return graph + + def draw_rag(labels, rag, img, border_color=None, node_color='#ffff00', edge_color='#00ff00', colormap=None, thresh=np.inf, desaturate=False, in_place=True): diff --git a/skimage/future/graph/tests/test_rag.py b/skimage/future/graph/tests/test_rag.py index e5882e20..8f1df909 100644 --- a/skimage/future/graph/tests/test_rag.py +++ b/skimage/future/graph/tests/test_rag.py @@ -196,3 +196,20 @@ def test_generic_rag_3d(): 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 len(g.nodes()) == 4 + assert len(g.edges()) == 4 \ No newline at end of file From 3cf6c8b1ce204d69f8654e960db42d298b3ed8ee Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 6 May 2015 00:50:58 +0530 Subject: [PATCH 02/18] removed unnecessary statement --- doc/examples/plot_rag_boundary.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/examples/plot_rag_boundary.py b/doc/examples/plot_rag_boundary.py index eeff1589..5324a2bd 100644 --- a/doc/examples/plot_rag_boundary.py +++ b/doc/examples/plot_rag_boundary.py @@ -17,8 +17,6 @@ labels = segmentation.slic(img, compactness=30, n_segments=400) edges = filters.sobel(gimg) edges_rgb = color.gray2rgb(edges) -mimg = segmentation.mark_boundaries(img, labels, (0,0,0)) - g = graph.rag_boundary(labels, edges) cmap = colors.ListedColormap(['#0000ff', '#ff0000']) From caba3041d170311c801ed84d63fa975aa265ac84 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 6 May 2015 00:55:04 +0530 Subject: [PATCH 03/18] indentation correction --- doc/examples/plot_rag_boundary.py | 2 +- skimage/future/graph/rag.py | 7 +++---- skimage/future/graph/tests/test_rag.py | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/doc/examples/plot_rag_boundary.py b/doc/examples/plot_rag_boundary.py index 5324a2bd..fb2e51a5 100644 --- a/doc/examples/plot_rag_boundary.py +++ b/doc/examples/plot_rag_boundary.py @@ -8,7 +8,7 @@ This example demonstrates construction of region boundary based RAGs with the """ from skimage.future import graph from skimage import data, segmentation, color, filters, io -from matplotlib import pyplot as plt, colors +from matplotlib import pyplot as colors img = data.coffee() gimg = color.rgb2gray(img) diff --git a/skimage/future/graph/rag.py b/skimage/future/graph/rag.py index 6c8fa502..ab6d2fc7 100644 --- a/skimage/future/graph/rag.py +++ b/skimage/future/graph/rag.py @@ -349,8 +349,7 @@ def rag_boundary(labels, edge_map, connectivity=2): nbr_indices = list(np.ndindex(*[2]*labels.ndim)) del nbr_indices[0] nbr_indices_arr = ([idx for idx in nbr_indices if np.linalg.norm(idx) - <= connectivity]) - + <= connectivity]) iter_shape = tuple(np.array(labels.shape) - 1) @@ -358,14 +357,14 @@ def rag_boundary(labels, edge_map, connectivity=2): index_arr = np.array(index) current = labels[index] - graph.add_node(current, {'labels':[current]}) + graph.add_node(current, {'labels': [current]}) for nbr_index in nbr_indices_arr: adjacent_idx = tuple(index_arr + nbr_index) adjacent = labels[adjacent_idx] - if current==adjacent: + if current == adjacent: continue if graph.has_edge(current, adjacent): diff --git a/skimage/future/graph/tests/test_rag.py b/skimage/future/graph/tests/test_rag.py index 8f1df909..4af3d854 100644 --- a/skimage/future/graph/tests/test_rag.py +++ b/skimage/future/graph/tests/test_rag.py @@ -202,8 +202,8 @@ 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 + edge_map[8, :] = 0.5 + edge_map[:, 8] = 1.0 labels[:8, :8] = 1 labels[:8, 8:] = 2 From 4041fc635410bd719adad93f2497c6ba227c2de5 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 6 May 2015 01:02:01 +0530 Subject: [PATCH 04/18] corrected colors import --- doc/examples/plot_rag_boundary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/examples/plot_rag_boundary.py b/doc/examples/plot_rag_boundary.py index fb2e51a5..b35ec221 100644 --- a/doc/examples/plot_rag_boundary.py +++ b/doc/examples/plot_rag_boundary.py @@ -8,7 +8,7 @@ This example demonstrates construction of region boundary based RAGs with the """ from skimage.future import graph from skimage import data, segmentation, color, filters, io -from matplotlib import pyplot as colors +from matplotlib import colors img = data.coffee() gimg = color.rgb2gray(img) From 4c05e6567068a7f082239558b4ca9aebe4dd2b42 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Thu, 17 Dec 2015 00:48:56 -0500 Subject: [PATCH 05/18] changed logic to use erosion/dilation --- skimage/future/graph/rag.py | 50 ++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/skimage/future/graph/rag.py b/skimage/future/graph/rag.py index ab6d2fc7..51019798 100644 --- a/skimage/future/graph/rag.py +++ b/skimage/future/graph/rag.py @@ -2,8 +2,9 @@ import networkx as nx import numpy as np from numpy.lib.stride_tricks import as_strided from scipy import ndimage as ndi +from scipy import sparse import math -from ... import draw, measure, segmentation, util, color +from ... import draw, measure, segmentation, util, color, morphology try: from matplotlib import colors from matplotlib import cm @@ -344,41 +345,32 @@ def rag_boundary(labels, edge_map, connectivity=2): """ graph = RAG() + eroded = morphology.erosion(labels) + dilated = morphology.dilation(labels) + boundaries = eroded != dilated - #Computing the relative indices of the neighbors - nbr_indices = list(np.ndindex(*[2]*labels.ndim)) - del nbr_indices[0] - nbr_indices_arr = ([idx for idx in nbr_indices if np.linalg.norm(idx) - <= connectivity]) + small_labels = eroded[boundaries] + large_labels = dilated[boundaries] + data = edge_map[boundaries] - iter_shape = tuple(np.array(labels.shape) - 1) + # coo logic sums values of duplicate indices + edge_data = sparse.coo_matrix((data, (small_labels, large_labels))).tocsr() - for index in np.ndindex(iter_shape): + # create a repeating array of [1., 1., ...] using stride tricks to save memory + counts = np.ones((1,), dtype=float) + counts = as_strided(counts, shape=small_labels.shape, strides=(0,)) + # use COO matrix to count the ones at each location + edge_count = sparse.coo_matrix((counts, (small_labels, large_labels))).tocsr() - index_arr = np.array(index) - current = labels[index] - graph.add_node(current, {'labels': [current]}) + edge_data.data /= edge_count.data - for nbr_index in nbr_indices_arr: + rows, cols = edge_data.nonzero() + graph_data = zip(rows, cols, edge_data.data) - adjacent_idx = tuple(index_arr + nbr_index) - adjacent = labels[adjacent_idx] + graph.add_weighted_edges_from(graph_data) - if current == adjacent: - continue - - if graph.has_edge(current, adjacent): - graph[current][adjacent]['pixel count'] += 2 - intensity = edge_map[index] + edge_map[adjacent_idx] - graph[current][adjacent]['total intensity'] += intensity - else: - graph.add_edge(current, adjacent) - graph[current][adjacent]['pixel count'] = 2 - intensity = edge_map[index] + edge_map[adjacent_idx] - graph[current][adjacent]['total intensity'] = intensity - - for (x, y, data) in graph.edges_iter(data=True): - data['weight'] = data['total intensity']/data['pixel count'] + for n in graph.nodes(): + graph.node[n].update({'labels': [n]}) return graph From a95c0bdddcc385052e31a56e88c5769616b0f773 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Thu, 17 Dec 2015 01:05:07 -0500 Subject: [PATCH 06/18] passing selem argument --- skimage/future/graph/rag.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/skimage/future/graph/rag.py b/skimage/future/graph/rag.py index 51019798..8cd09106 100644 --- a/skimage/future/graph/rag.py +++ b/skimage/future/graph/rag.py @@ -345,8 +345,10 @@ def rag_boundary(labels, edge_map, connectivity=2): """ graph = RAG() - eroded = morphology.erosion(labels) - dilated = morphology.dilation(labels) + fp = ndi.generate_binary_structure(labels.ndim, connectivity) + print(fp) + eroded = morphology.erosion(labels, selem=fp) + dilated = morphology.dilation(labels, selem=fp) boundaries = eroded != dilated small_labels = eroded[boundaries] From e8f2805d644b61085010b4e2918473fd640f44b4 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 6 Jan 2016 15:04:09 -0500 Subject: [PATCH 07/18] changed to eosion/dilation logic --- doc/examples/plot_rag_boundary.py | 5 ++-- skimage/future/graph/rag.py | 50 +++++++++++++++---------------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/doc/examples/plot_rag_boundary.py b/doc/examples/plot_rag_boundary.py index b35ec221..c975f884 100644 --- a/doc/examples/plot_rag_boundary.py +++ b/doc/examples/plot_rag_boundary.py @@ -9,6 +9,7 @@ This example demonstrates construction of region boundary based RAGs with the from skimage.future import graph from skimage import data, segmentation, color, filters, io from matplotlib import colors +import numpy as np img = data.coffee() gimg = color.rgb2gray(img) @@ -19,8 +20,8 @@ edges_rgb = color.gray2rgb(edges) g = graph.rag_boundary(labels, edges) -cmap = colors.ListedColormap(['#0000ff', '#ff0000']) -out = graph.draw_rag(labels, g, edges_rgb, node_color="#ffff00", colormap=cmap) +out = graph.draw_rag(labels, g, edges_rgb, node_color="#ffff00", + colormap='plasma') io.imshow(out) io.show() diff --git a/skimage/future/graph/rag.py b/skimage/future/graph/rag.py index 8cd09106..fc6e1d6f 100644 --- a/skimage/future/graph/rag.py +++ b/skimage/future/graph/rag.py @@ -344,37 +344,35 @@ def rag_boundary(labels, edge_map, connectivity=2): """ - graph = RAG() - fp = ndi.generate_binary_structure(labels.ndim, connectivity) - print(fp) - eroded = morphology.erosion(labels, selem=fp) - dilated = morphology.dilation(labels, selem=fp) - boundaries = eroded != dilated + conn = ndi.generate_binary_structure(labels.ndim, connectivity) + eroded = ndi.grey_erosion(labels, footprint=conn) + dilated = ndi.grey_dilation(labels, footprint=conn) + boundaries0 = (eroded != labels) + boundaries1 = (dilated != labels) + labels_small = np.concatenate((eroded[boundaries0], labels[boundaries1])) + labels_large = np.concatenate((labels[boundaries0], dilated[boundaries1])) + n = np.max(labels_large) + 1 - small_labels = eroded[boundaries] - large_labels = dilated[boundaries] - data = edge_map[boundaries] + # use a dummy broadcast array as data for RAG + ones = np.broadcast_to(np.ones((1,), dtype=np.int_), + labels_small.shape) + count_matrix = sparse.coo_matrix((ones, (labels_small, labels_large)), + dtype=np.int_, shape=(n, n)).tocsr() + data = np.concatenate((edge_map[boundaries0], edge_map[boundaries1])) - # coo logic sums values of duplicate indices - edge_data = sparse.coo_matrix((data, (small_labels, large_labels))).tocsr() + data_coo = sparse.coo_matrix((data, (labels_small, labels_large))) + graph_matrix = data_coo.tocsr() + graph_matrix.data /= count_matrix.data - # create a repeating array of [1., 1., ...] using stride tricks to save memory - counts = np.ones((1,), dtype=float) - counts = as_strided(counts, shape=small_labels.shape, strides=(0,)) - # use COO matrix to count the ones at each location - edge_count = sparse.coo_matrix((counts, (small_labels, large_labels))).tocsr() + rag = nx.Graph() + rows, cols = graph_matrix.nonzero() + graph_data = zip(rows, cols, graph_matrix.data) + rag.add_weighted_edges_from(graph_data) - edge_data.data /= edge_count.data + for n in rag.nodes(): + rag.node[n].update({'labels': [n]}) - rows, cols = edge_data.nonzero() - graph_data = zip(rows, cols, edge_data.data) - - graph.add_weighted_edges_from(graph_data) - - for n in graph.nodes(): - graph.node[n].update({'labels': [n]}) - - return graph + return rag def draw_rag(labels, rag, img, border_color=None, node_color='#ffff00', From 422dfc6c22178071e46b001920891e5ff254e63a Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 6 Jan 2016 15:17:48 -0500 Subject: [PATCH 08/18] cleanup --- doc/examples/plot_rag_boundary.py | 2 -- skimage/future/graph/__init__.py | 2 +- skimage/future/graph/rag.py | 6 +++--- skimage/future/graph/tests/test_rag.py | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/doc/examples/plot_rag_boundary.py b/doc/examples/plot_rag_boundary.py index c975f884..5063d96a 100644 --- a/doc/examples/plot_rag_boundary.py +++ b/doc/examples/plot_rag_boundary.py @@ -8,8 +8,6 @@ This example demonstrates construction of region boundary based RAGs with the """ from skimage.future import graph from skimage import data, segmentation, color, filters, io -from matplotlib import colors -import numpy as np img = data.coffee() gimg = color.rgb2gray(img) diff --git a/skimage/future/graph/__init__.py b/skimage/future/graph/__init__.py index e73c8d19..d685a793 100644 --- a/skimage/future/graph/__init__.py +++ b/skimage/future/graph/__init__.py @@ -9,5 +9,5 @@ __all__ = ['rag_mean_color', 'ncut', 'draw_rag', 'merge_hierarchical', - 'rag_boundary' + 'rag_boundary', 'RAG'] diff --git a/skimage/future/graph/rag.py b/skimage/future/graph/rag.py index fc6e1d6f..566c7261 100644 --- a/skimage/future/graph/rag.py +++ b/skimage/future/graph/rag.py @@ -4,7 +4,7 @@ from numpy.lib.stride_tricks import as_strided from scipy import ndimage as ndi from scipy import sparse import math -from ... import draw, measure, segmentation, util, color, morphology +from ... import draw, measure, segmentation, util, color try: from matplotlib import colors from matplotlib import cm @@ -364,10 +364,10 @@ def rag_boundary(labels, edge_map, connectivity=2): graph_matrix = data_coo.tocsr() graph_matrix.data /= count_matrix.data - rag = nx.Graph() + rag = RAG() rows, cols = graph_matrix.nonzero() graph_data = zip(rows, cols, graph_matrix.data) - rag.add_weighted_edges_from(graph_data) + rag.add_weighted_edges_from(graph_data, attr='weight') for n in rag.nodes(): rag.node[n].update({'labels': [n]}) diff --git a/skimage/future/graph/tests/test_rag.py b/skimage/future/graph/tests/test_rag.py index 4af3d854..dafa0ddc 100644 --- a/skimage/future/graph/tests/test_rag.py +++ b/skimage/future/graph/tests/test_rag.py @@ -212,4 +212,4 @@ def test_rag_boundary(): g = graph.rag_boundary(labels, edge_map, connectivity=1) assert len(g.nodes()) == 4 - assert len(g.edges()) == 4 \ No newline at end of file + assert len(g.edges()) == 4 From a5f6db59cbb2b01ac173ec4a13237c53ee0f5d84 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 6 Jan 2016 15:42:10 -0500 Subject: [PATCH 09/18] doc example --- skimage/future/graph/rag.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/future/graph/rag.py b/skimage/future/graph/rag.py index 566c7261..4faea16c 100644 --- a/skimage/future/graph/rag.py +++ b/skimage/future/graph/rag.py @@ -340,7 +340,7 @@ def rag_boundary(labels, edge_map, connectivity=2): >>> img = data.chelsea() >>> labels = segmentation.slic(img) >>> edge_map = filters.sobel(color.rgb2gray(img)) - >>> rag = graph.rag_mean_color(labels, edge_map) + >>> rag = graph.rag_boundary(labels, edge_map) """ From ea18fcb99be6a88d8e883672ed050687498a6140 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 6 Jan 2016 16:23:43 -0500 Subject: [PATCH 10/18] use as strided --- skimage/future/graph/rag.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skimage/future/graph/rag.py b/skimage/future/graph/rag.py index 4faea16c..dd45f2fc 100644 --- a/skimage/future/graph/rag.py +++ b/skimage/future/graph/rag.py @@ -354,8 +354,8 @@ def rag_boundary(labels, edge_map, connectivity=2): n = np.max(labels_large) + 1 # use a dummy broadcast array as data for RAG - ones = np.broadcast_to(np.ones((1,), dtype=np.int_), - labels_small.shape) + ones = as_strided(np.ones((1,), dtype=np.float), shape=labels_small.shape, + strides=(0,)) count_matrix = sparse.coo_matrix((ones, (labels_small, labels_large)), dtype=np.int_, shape=(n, n)).tocsr() data = np.concatenate((edge_map[boundaries0], edge_map[boundaries1])) From a4a406349bfdd5cb3a1fc8660893dc9be353eaf5 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 6 Jan 2016 19:58:40 -0500 Subject: [PATCH 11/18] moved example file --- doc/examples/{ => segmentation}/plot_rag_boundary.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/examples/{ => segmentation}/plot_rag_boundary.py (100%) diff --git a/doc/examples/plot_rag_boundary.py b/doc/examples/segmentation/plot_rag_boundary.py similarity index 100% rename from doc/examples/plot_rag_boundary.py rename to doc/examples/segmentation/plot_rag_boundary.py From 772d1ccc15ffbf86798d85e8a332b51569d37b46 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 6 Jan 2016 20:23:55 -0500 Subject: [PATCH 12/18] changed colormap to jet --- doc/examples/segmentation/plot_rag_boundary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/examples/segmentation/plot_rag_boundary.py b/doc/examples/segmentation/plot_rag_boundary.py index 5063d96a..4b29b6bd 100644 --- a/doc/examples/segmentation/plot_rag_boundary.py +++ b/doc/examples/segmentation/plot_rag_boundary.py @@ -19,7 +19,7 @@ edges_rgb = color.gray2rgb(edges) g = graph.rag_boundary(labels, edges) out = graph.draw_rag(labels, g, edges_rgb, node_color="#ffff00", - colormap='plasma') + colormap='jet') io.imshow(out) io.show() From def8ca7f753905bced082b8c0369747e1a934a8a Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 6 Jan 2016 21:29:42 -0500 Subject: [PATCH 13/18] change mcap to viridis --- doc/examples/segmentation/plot_rag_boundary.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/examples/segmentation/plot_rag_boundary.py b/doc/examples/segmentation/plot_rag_boundary.py index 4b29b6bd..4d909360 100644 --- a/doc/examples/segmentation/plot_rag_boundary.py +++ b/doc/examples/segmentation/plot_rag_boundary.py @@ -8,6 +8,8 @@ This example demonstrates construction of region boundary based RAGs with the """ from skimage.future import graph from skimage import data, segmentation, color, filters, io +from skimage.util.colormap import viridis + img = data.coffee() gimg = color.rgb2gray(img) @@ -18,8 +20,8 @@ edges_rgb = color.gray2rgb(edges) g = graph.rag_boundary(labels, edges) -out = graph.draw_rag(labels, g, edges_rgb, node_color="#ffff00", - colormap='jet') +out = graph.draw_rag(labels, g, edges_rgb, node_color="#999999", + colormap=viridis) io.imshow(out) io.show() From f9dfa1d81d139dc833af5870c7c8b1e1604ffc25 Mon Sep 17 00:00:00 2001 From: Juan Nunez-Iglesias Date: Fri, 8 Jan 2016 17:25:10 +1100 Subject: [PATCH 14/18] Make mean boundary RAG testing more robust --- skimage/future/graph/tests/test_rag.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/skimage/future/graph/tests/test_rag.py b/skimage/future/graph/tests/test_rag.py index dafa0ddc..27d31a99 100644 --- a/skimage/future/graph/tests/test_rag.py +++ b/skimage/future/graph/tests/test_rag.py @@ -211,5 +211,7 @@ def test_rag_boundary(): labels[8:, 8:] = 4 g = graph.rag_boundary(labels, edge_map, connectivity=1) - assert len(g.nodes()) == 4 - assert len(g.edges()) == 4 + assert set(g.nodes()) == set([1, 2, 3, 4]) + assert set(g.edges()) == set([(1, 2), (1, 3), (2, 4), (3, 4)]) + assert g[1][3]['weight'] == 0.25 + assert g[2][4]['weight'] == 0.34375 From 30145ab7f4d59b50aa40adffd753968e327c34eb Mon Sep 17 00:00:00 2001 From: Juan Nunez-Iglesias Date: Fri, 8 Jan 2016 22:10:20 +1100 Subject: [PATCH 15/18] Use function to update graph edges from CSR --- skimage/future/graph/rag.py | 44 ++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/skimage/future/graph/rag.py b/skimage/future/graph/rag.py index dd45f2fc..ab31171e 100644 --- a/skimage/future/graph/rag.py +++ b/skimage/future/graph/rag.py @@ -12,6 +12,45 @@ except ImportError: pass +def _edge_generator_from_csr(csr_matrix): + """Yield weighted edge triples for use by NetworkX from a CSR matrix. + + This function is a straight rewrite of + `networkx.convert_matrix._csr_gen_triples`. Since that is a private + function, it is safer to include our own here. + + Parameters + ---------- + csr_matrix : scipy.sparse.csr_matrix + The input matrix. An edge (i, j, w) will be yielded if there is a + data value for coordinates (i, j) in the matrix, even if that value + is 0. + + Yields + ------ + i, j, w : (int, int, float) tuples + Each value `w` in the matrix along with its coordinates (i, j). + + Examples + -------- + + >>> dense = np.eye(2, dtype=np.float) + >>> csr = sparse.csr_matrix(dense) + >>> edges = _edge_generator_from_csr(csr) + >>> type(edges) + generator + >>> list(edges) + [(0, 0, 1.0), (1, 1, 1.0)] + """ + nrows = csr_matrix.shape[0] + values = csr_matrix.data + indptr = csr_matrix.indptr + col_indices = csr_matrix.indices + for i in range(nrows): + for j in range(indptr[i], indptr[i + 1]): + yield i, col_indices[j], data[j] + + def min_weight(graph, src, dst, n): """Callback to handle merging nodes by choosing minimum weight. @@ -365,9 +404,8 @@ def rag_boundary(labels, edge_map, connectivity=2): graph_matrix.data /= count_matrix.data rag = RAG() - rows, cols = graph_matrix.nonzero() - graph_data = zip(rows, cols, graph_matrix.data) - rag.add_weighted_edges_from(graph_data, attr='weight') + rag.add_weighted_edges_from(_edge_generator_from_csr(graph_matrix), + weight='weight') for n in rag.nodes(): rag.node[n].update({'labels': [n]}) From 802214d5acedc32507e9c1a041afdcb96c6963b0 Mon Sep 17 00:00:00 2001 From: Juan Nunez-Iglesias Date: Fri, 8 Jan 2016 22:11:31 +1100 Subject: [PATCH 16/18] Hold pixel count in mean boundary RAG edges This value is needed to combine edges when merging nodes. --- skimage/future/graph/rag.py | 2 ++ skimage/future/graph/tests/test_rag.py | 1 + 2 files changed, 3 insertions(+) diff --git a/skimage/future/graph/rag.py b/skimage/future/graph/rag.py index ab31171e..646a7cc6 100644 --- a/skimage/future/graph/rag.py +++ b/skimage/future/graph/rag.py @@ -406,6 +406,8 @@ def rag_boundary(labels, edge_map, connectivity=2): rag = RAG() rag.add_weighted_edges_from(_edge_generator_from_csr(graph_matrix), weight='weight') + rag.add_weighted_edges_from(_edge_generator_from_csr(count_matrix), + weight='count') for n in rag.nodes(): rag.node[n].update({'labels': [n]}) diff --git a/skimage/future/graph/tests/test_rag.py b/skimage/future/graph/tests/test_rag.py index 27d31a99..4b2e4cff 100644 --- a/skimage/future/graph/tests/test_rag.py +++ b/skimage/future/graph/tests/test_rag.py @@ -215,3 +215,4 @@ def test_rag_boundary(): assert set(g.edges()) == set([(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 From 753c8caf4ee0f6d18dfd6b6722568979f1550735 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Fri, 8 Jan 2016 14:11:56 -0500 Subject: [PATCH 17/18] correct variable name mistake --- skimage/future/graph/rag.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/future/graph/rag.py b/skimage/future/graph/rag.py index 646a7cc6..739c3010 100644 --- a/skimage/future/graph/rag.py +++ b/skimage/future/graph/rag.py @@ -48,7 +48,7 @@ def _edge_generator_from_csr(csr_matrix): col_indices = csr_matrix.indices for i in range(nrows): for j in range(indptr[i], indptr[i + 1]): - yield i, col_indices[j], data[j] + yield i, col_indices[j], values[j] def min_weight(graph, src, dst, n): From 22bf68d9b42322f59ba76441bdade2e206cd8f4a Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Fri, 8 Jan 2016 21:49:01 -0500 Subject: [PATCH 18/18] removed failing doctest line --- skimage/future/graph/rag.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/skimage/future/graph/rag.py b/skimage/future/graph/rag.py index 739c3010..dae5bbd1 100644 --- a/skimage/future/graph/rag.py +++ b/skimage/future/graph/rag.py @@ -37,8 +37,6 @@ def _edge_generator_from_csr(csr_matrix): >>> dense = np.eye(2, dtype=np.float) >>> csr = sparse.csr_matrix(dense) >>> edges = _edge_generator_from_csr(csr) - >>> type(edges) - generator >>> list(edges) [(0, 0, 1.0), (1, 1, 1.0)] """