From 486f935db8f8f6e424524905826fb3874cc48a58 Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 2 Jul 2014 00:19:11 +0530 Subject: [PATCH] Rename methods and edit docstrings --- ...ag_meancolor.py => plot_rag_mean_color.py} | 6 +- skimage/graph/__init__.py | 8 +-- skimage/graph/graph_cut.py | 9 ++- skimage/graph/rag.py | 67 ++++++++++--------- skimage/graph/tests/test_rag.py | 4 +- 5 files changed, 50 insertions(+), 44 deletions(-) rename doc/examples/{plot_rag_meancolor.py => plot_rag_mean_color.py} (77%) diff --git a/doc/examples/plot_rag_meancolor.py b/doc/examples/plot_rag_mean_color.py similarity index 77% rename from doc/examples/plot_rag_meancolor.py rename to doc/examples/plot_rag_mean_color.py index 11aca77c..7a1d24b9 100644 --- a/doc/examples/plot_rag_meancolor.py +++ b/doc/examples/plot_rag_mean_color.py @@ -3,7 +3,7 @@ RAG Thresholding ================ -This examples constructs a Region Adjacency Graph (RAG) and merges regions +This example constructs a Region Adjacency Graph (RAG) and merges regions which are similar in color. We construct a RAG and define edges as the difference in mean color. We then join regions with similar mean color. @@ -18,8 +18,8 @@ img = data.coffee() labels1 = segmentation.slic(img, compactness=30, n_segments=400) out1 = color.label2rgb(labels1, img, kind='avg') -g = graph.rag_meancolor(img, labels1) -labels2 = graph.threshold_cut(labels1, g, 30) +g = graph.rag_mean_color(img, labels1) +labels2 = graph.cut_threshold(labels1, g, 30) out2 = color.label2rgb(labels2, img, kind='avg') plt.figure() diff --git a/skimage/graph/__init__.py b/skimage/graph/__init__.py index 90da2088..ade8326a 100644 --- a/skimage/graph/__init__.py +++ b/skimage/graph/__init__.py @@ -1,7 +1,7 @@ from .spath import shortest_path from .mcp import MCP, MCP_Geometric, MCP_Connect, MCP_Flexible, route_through_array -from .rag import rag_meancolor -from .graph_cut import threshold_cut +from .rag import rag_mean_color +from .graph_cut import cut_threshold __all__ = ['shortest_path', 'MCP', @@ -9,5 +9,5 @@ __all__ = ['shortest_path', 'MCP_Connect', 'MCP_Flexible', 'route_through_array', - 'rag_meancolor', - 'threshold_cut'] + 'rag_mean_color', + 'cut_threshold'] diff --git a/skimage/graph/graph_cut.py b/skimage/graph/graph_cut.py index 165091b1..a870ff9e 100644 --- a/skimage/graph/graph_cut.py +++ b/skimage/graph/graph_cut.py @@ -2,7 +2,7 @@ import networkx as nx import numpy as np -def threshold_cut(labels, rag, thresh): +def cut_threshold(labels, rag, thresh): """Combine regions seperated by weight less than threshold. Given an image's labels and its RAG, output new labels by @@ -16,8 +16,8 @@ def threshold_cut(labels, rag, thresh): rag : RAG The region adjacency graph. thresh : float - The threshold, regions with edge weights less than this - are combined. + The threshold. Regions connected by edges with smaller weights are + combined. Returns ------- @@ -46,6 +46,9 @@ def threshold_cut(labels, rag, thresh): comps = nx.connected_components(rag) + # We construct an array which can map old labels to the new ones. + # All the labels within a connected component are assigned to a single + # label in the output. map_array = np.arange(labels.max() + 1, dtype=labels.dtype) for i, nodes in enumerate(comps): for node in nodes: diff --git a/skimage/graph/rag.py b/skimage/graph/rag.py index 39bd0a3e..e20f7c5a 100644 --- a/skimage/graph/rag.py +++ b/skimage/graph/rag.py @@ -4,18 +4,18 @@ from scipy.ndimage import filters from scipy import ndimage as nd -def min_weight(g, src, dst, n): +def min_weight(graph, src, dst, n): """Callback to handle merging nodes by choosing minimum weight. Returns either the weight between (`src`, `n`) or (`dst`, `n`) - in `g` or the minumum of the two when both exist. + in `graph` or the minumum of the two when both exist. Parameters ---------- - g : RAG + graph : RAG The graph under consideration. src, dst : int - The verices in `g` to be merged. + The verices in `graph` to be merged. n : int A neighbor of `src` or `dst` or both. @@ -28,8 +28,8 @@ def min_weight(g, src, dst, n): """ # cover the cases where n only has edge to either `src` or `dst` - w1 = g[n].get(src, {'weight': np.inf})['weight'] - w2 = g[n].get(dst, {'weight': np.inf})['weight'] + w1 = graph[n].get(src, {'weight': np.inf})['weight'] + w2 = graph[n].get(dst, {'weight': np.inf})['weight'] return min(w1, w2) @@ -50,7 +50,7 @@ class RAG(nx.Graph): Parameters ---------- src, dst : int - Nodes to be merged. The resulting node will have ID `dst`. + Nodes to be merged. weight_func : callable, optional Function to decide edge weight of edges incident on the new node. For each neighbor `n` for `src and `dst`, `weight_func` will be @@ -63,8 +63,9 @@ class RAG(nx.Graph): The dict of keyword arguments passed to the `weight_func`. """ - neighbors = (set(self.neighbors(src)) & set( - self.neighbors(dst))) - set([src, dst]) + src_nbrs = set(self.neighbors(src)) + dst_nbrs = set(self.neighbors(dst)) + neighbors = (src_nbrs & dst_nbrs) - set([src, dst]) for neighbor in neighbors: w = weight_func(self, src, dst, neighbor, *extra_arguments, @@ -75,7 +76,7 @@ class RAG(nx.Graph): self.remove_node(src) -def _add_edge_filter(values, g): +def _add_edge_filter(values, graph): """Create edge in `g` between the first element of `values` and the rest. Add an edge between the first element in `values` and @@ -86,31 +87,32 @@ def _add_edge_filter(values, g): ---------- values : array The array to process. - g : RAG + graph : RAG The graph to add edges in. Returns ------- 0 : int - Always returns 0. + Always returns 0. The return value is required so that `generic_fitler` + can put it in the output array. """ values = values.astype(int) current = values[0] for value in values[1:]: - g.add_edge(current, value) + graph.add_edge(current, value) return 0 -def rag_meancolor(image, labels, connectivity=2): +def rag_mean_color(image, labels, connectivity=2): """Compute the Region Adjacency Graph using mean colors. Given an image and its initial segmentation, this method constructs the corresponsing Region Adjacency Graph (RAG). Each node in the RAG - represents a set pixels within `image` with the same - label in `labels`. The weight between two adjacent regions is the - difference in their mean color. + represents a set of pixels within `image` with the same label in `labels`. + The weight between two adjacent regions is the difference in their mean + color. Parameters ---------- @@ -145,7 +147,7 @@ def rag_meancolor(image, labels, connectivity=2): http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.11.5274 """ - g = RAG() + graph = RAG() # The footprint is constructed in such a way that the first # element in the array being passed to _add_edge_filter is @@ -173,24 +175,25 @@ def rag_meancolor(image, labels, connectivity=2): footprint=fp, mode='nearest', output=np.zeros(labels.shape, dtype=np.uint8), - extra_arguments=(g,)) + extra_arguments=(graph,)) - for n in g: - g.node[n].update({'labels': [n], - 'pixel count': 0, - 'total color': np.array([0, 0, 0], dtype=np.double)}) + for n in graph: + graph.node[n].update({'labels': [n], + 'pixel count': 0, + 'total color': np.array([0, 0, 0], + dtype=np.double)}) for index in np.ndindex(labels.shape): current = labels[index] - g.node[current]['pixel count'] += 1 - g.node[current]['total color'] += image[index] + graph.node[current]['pixel count'] += 1 + graph.node[current]['total color'] += image[index] - for n in g: - g.node[n]['mean color'] = (g.node[n]['total color'] / - g.node[n]['pixel count']) + for n in graph: + graph.node[n]['mean color'] = (graph.node[n]['total color'] / + graph.node[n]['pixel count']) - for x, y in g.edges_iter(): - diff = g.node[x]['mean color'] - g.node[y]['mean color'] - g[x][y]['weight'] = np.linalg.norm(diff) + for x, y in graph.edges_iter(): + diff = graph.node[x]['mean color'] - graph.node[y]['mean color'] + graph[x][y]['weight'] = np.linalg.norm(diff) - return g + return graph diff --git a/skimage/graph/tests/test_rag.py b/skimage/graph/tests/test_rag.py index 37c31887..7b4551f4 100644 --- a/skimage/graph/tests/test_rag.py +++ b/skimage/graph/tests/test_rag.py @@ -56,8 +56,8 @@ def test_threshold_cut(): labels[50:, :50] = 2 labels[50:, 50:] = 3 - rag = graph.rag_meancolor(img, labels) - new_labels = graph.threshold_cut(labels, rag, 10) + rag = graph.rag_mean_color(img, labels) + new_labels = graph.cut_threshold(labels, rag, 10) # Two labels assert new_labels.max() == 1