From 4005749a61f6022e3adc509b775f9d4c8a5a2c2d Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Tue, 5 Aug 2014 23:05:15 +0530 Subject: [PATCH] rebase and change API to support mpl colorspec --- doc/examples/plot_rag_draw.py | 13 ++--- skimage/graph/__init__.py | 2 + skimage/graph/rag.py | 89 ++++++++++++++++++----------------- 3 files changed, 56 insertions(+), 48 deletions(-) diff --git a/doc/examples/plot_rag_draw.py b/doc/examples/plot_rag_draw.py index 51a33dbd..21dbbc28 100644 --- a/doc/examples/plot_rag_draw.py +++ b/doc/examples/plot_rag_draw.py @@ -1,25 +1,26 @@ """ -=========== -RAG Drawing -=========== +===================================== +Drawing Region Adjacency Graphs (RAGs) +====================================== This example constructs a Region Adjacency Graph (RAG) and draws it with the `rag_draw` method. """ from skimage import graph, data, segmentation -from matplotlib import pyplot as plt +from matplotlib import pyplot as plt, colors img = data.coffee() labels = segmentation.slic(img, compactness=30, n_segments=400) g = graph.rag_mean_color(img, labels) -out = graph.rag_draw(labels, g, img) +out = graph.draw_rag(labels, g, img) plt.figure() plt.title("RAG with all edges shown in green.") plt.imshow(out) -out = graph.rag_draw(labels, g, img, high_color=(1, 0, 0), thresh=30) +cmap = colors.ListedColormap(['cyan', 'red']) +out = graph.draw_rag(labels, g, img, colormap=cmap, thresh=30) plt.figure() plt.title("RAG with edge weights less than 30, color " "mapped between green and red.") diff --git a/skimage/graph/__init__.py b/skimage/graph/__init__.py index 2f1162d3..2cd422ba 100644 --- a/skimage/graph/__init__.py +++ b/skimage/graph/__init__.py @@ -3,6 +3,7 @@ from .mcp import MCP, MCP_Geometric, MCP_Connect, MCP_Flexible, route_through_ar from .rag import rag_mean_color, RAG from .graph_cut import cut_threshold, cut_normalized from .rag import rag_mean_color, RAG, rag_draw +from .rag import rag_mean_color, RAG, draw_rag from .graph_cut import cut_threshold ncut = cut_normalized @@ -18,4 +19,5 @@ __all__ = ['shortest_path', 'cut_normalized', 'ncut', 'rag_draw', + 'draw_rag', 'RAG'] diff --git a/skimage/graph/rag.py b/skimage/graph/rag.py index 9368f558..4447c4e3 100644 --- a/skimage/graph/rag.py +++ b/skimage/graph/rag.py @@ -9,11 +9,21 @@ except ImportError: raise ImportError(msg) import warnings warnings.warn(msg) + import numpy as np from scipy.ndimage import filters from scipy import ndimage as nd +<<<<<<< HEAD import math from .. import draw, measure, segmentation +======= +from .. import draw +from .. import measure +from .. import segmentation +from matplotlib import colors +from matplotlib import cm +from .. import util +>>>>>>> rebase and change API to support mpl colorspec def min_weight(graph, src, dst, n): @@ -239,8 +249,8 @@ def rag_mean_color(image, labels, connectivity=2, mode='distance', return graph -def rag_draw(labels, rag, img, border_color=(0, 0, 0), node_color = (1, 1, 0), - low_color = (0, 1, 0), high_color=None, thresh=np.inf): +def draw_rag(labels, rag, img, border_color=None, node_color='yellow', + edge_color='green', colormap=None, thresh=np.inf): """Draw a Region Adjacency Graph on an image. Given a labelled image and its corresponding RAG, draw the nodes and edges @@ -249,30 +259,24 @@ def rag_draw(labels, rag, img, border_color=(0, 0, 0), node_color = (1, 1, 0), Parameters ---------- - labels : ndarray, shape(M, N, [..., P,]) - The labelled image. This should have one dimension less than - `img`. If `img` has dimensions `(M, N, 3)` `labels` should have - dimensions `(M, N)`. + labels : ndarray, shape(M, N) + The labelled image. rag : RAG The Region Adjacency Graph. - img : ndarray, shape(M, N, [..., P,] 3) + img : ndarray, shape(M, N, 3) Input image. - border_color : length-3 sequence, optional - RGB color of the border of regions. Specifying `None` won't draw - the border. Black by default. - node_color : length-3 sequeunce, optional - RGB color of the centroid of nodes. Yellow by default. - low_color : length-3 sequeunce, optional - RGB color of the edges. If `high_color` is not specified, all edges - are draw with `low_color`. Green by default. - high_color : length-3 sequeunce, optional - RGB color of the edges with high weight. If specified, the edges are - color mapped between `low_color` and `high_color` depending on their - weight. Edges with low weights are more like `low_color` whereas edges - with high weights are more like `high_color`. - thresh : float, optiona; + border_color : colorspec, optional + Any matplotlib colorspec. + node_color : colorspec, optional + Any matplotlib colorspec. Yellow by default. + edge_color : colorspec, optional + Any matplotlib colorspec. Green by default. + colormap : colormap, optional + Any matplotlib colormap. If specified the edges are colormapped with + the specified color map. + thresh : float, optional Edges with weight below `thresh` are not drawn, or considered for color - mapping in case `high_color` is specified. + mapping. Returns ------- @@ -282,41 +286,44 @@ def rag_draw(labels, rag, img, border_color=(0, 0, 0), node_color = (1, 1, 0), Examples -------- >>> from skimage import data, graph, segmentation - >>> img = data.lena() + >>> img = data.coffee() >>> labels = segmentation.slic(img) >>> g = graph.rag_mean_color(img, labels) >>> out = graph.rag_draw(labels, g, img) """ rag = rag.copy() - rag_labels = labels.copy() - out = img.copy() + out = util.img_as_float(img) + cc = colors.ColorConverter() - low_color = np.array(low_color) - - if not high_color is None: - high_color = np.array(high_color) + edge_color = cc.to_rgb(edge_color) + node_color = cc.to_rgb(node_color) # Handling the case where one node has multiple labels # offset is 1 so that regionprops does not ignore 0 offset = 1 + map_array = np.arange(labels.max() + 1) for n, d in rag.nodes_iter(data=True): - for l in d['labels']: - rag_labels[labels == l] = offset + for label in d['labels']: + map_array[label] = offset offset += 1 + rag_labels = map_array[labels] + regions = measure.regionprops(rag_labels) for region in regions: # Because we kept the offset as 1 rag.node[region['label'] - 1]['centroid'] = region['centroid'] if not border_color is None: + border_color = cc.to_rgb(border_color) out = segmentation.mark_boundaries(out, rag_labels, color=border_color) - if not high_color is None: - max_weight = max([d['weight'] for x, y, d in rag.edges_iter(data=True) - if d['weight'] < thresh]) - min_weight = min([d['weight'] for x, y, d in rag.edges_iter(data=True) - if d['weight'] < thresh]) + if colormap is not None: + edge_weight_list = [d['weight'] for x, y, d in + rag.edges_iter(data=True) if d['weight'] < thresh] + norm = colors.Normalize() + norm.autoscale(edge_weight_list) + smap = cm.ScalarMappable(norm, colormap) for n1, n2, data in rag.edges_iter(data=True): @@ -327,13 +334,11 @@ def rag_draw(labels, rag, img, border_color=(0, 0, 0), node_color = (1, 1, 0), line = draw.line(r1, c1, r2, c2) - if not high_color is None: - norm_weight = ((rag[n1][n2]['weight'] - min_weight) / - (max_weight - min_weight)) - out[line] = (norm_weight * high_color + - (1 - norm_weight) * low_color) + if colormap is not None: + current_color = smap.to_rgba([data['weight']])[0][:-1] + out[line] = current_color else: - out[line] = low_color + out[line] = edge_color circle = draw.circle(r1, c1, 2) out[circle] = node_color