Merge pull request #1087 from vighneshbirodkar/rag_draw

RAG drawing function
This commit is contained in:
Juan Nunez-Iglesias
2014-08-18 10:05:58 -05:00
5 changed files with 163 additions and 5 deletions
+39
View File
@@ -0,0 +1,39 @@
"""
=====================================
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, colors
img = data.coffee()
labels = segmentation.slic(img, compactness=30, n_segments=400)
g = graph.rag_mean_color(img, labels)
out = graph.draw_rag(labels, g, img)
plt.figure()
plt.title("RAG with all edges shown in green.")
plt.imshow(out)
# The color palette used was taken from
# http://www.colorcombos.com/color-schemes/2/ColorCombo2.html
cmap = colors.ListedColormap(['#6599FF', '#ff9900'])
out = graph.draw_rag(labels, g, img, node_color="#ffde00", colormap=cmap,
thresh=30, desaturate=True)
plt.figure()
plt.title("RAG with edge weights less than 30, color "
"mapped between blue and orange.")
plt.imshow(out)
plt.figure()
plt.title("All edges drawn with cubehelix colormap")
cmap = plt.get_cmap('cubehelix')
out = graph.draw_rag(labels, g, img, colormap=cmap,
desaturate=True)
plt.imshow(out)
plt.show()
+6 -3
View File
@@ -14,9 +14,12 @@ http://scikit-image.org
New Features
------------
Region Adjacency Graphs
- Color distance RAGs (#1031)
- Threshold Cut on RAGs (#1031)
- Similarity RAGs (#1080)
- Normalized Cut on RAGs (#1080)
- RAG Drawing (#1087)
Improvements
------------
+3 -1
View File
@@ -1,9 +1,10 @@
from .spath import shortest_path
from .mcp import MCP, MCP_Geometric, MCP_Connect, MCP_Flexible, route_through_array
from .rag import rag_mean_color, RAG
from .graph_cut import cut_threshold, cut_normalized
from .rag import rag_mean_color, RAG, draw_rag
ncut = cut_normalized
__all__ = ['shortest_path',
'MCP',
'MCP_Geometric',
@@ -14,4 +15,5 @@ __all__ = ['shortest_path',
'cut_threshold',
'cut_normalized',
'ncut',
'draw_rag',
'RAG']
+1 -1
View File
@@ -128,7 +128,7 @@ def cut_normalized(labels, rag, thresh=0.001, num_cuts=10, in_place=True,
_ncut_relabel(rag, thresh, num_cuts)
map_array = np.zeros(labels.max() + 1)
map_array = np.zeros(labels.max() + 1, dtype=labels.dtype)
# Mapping from old labels to new
for n, d in rag.nodes_iter(data=True):
map_array[d['labels']] = d['ncut label']
+114
View File
@@ -9,10 +9,17 @@ 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
import math
from .. import draw, measure, segmentation, util, color
try:
from matplotlib import colors
from matplotlib import cm
except ImportError:
pass
def min_weight(graph, src, dst, n):
@@ -237,3 +244,110 @@ def rag_mean_color(image, labels, connectivity=2, mode='distance',
raise ValueError("The mode '%s' is not recognised" % mode)
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):
"""Draw a Region Adjacency Graph on an image.
Given a labelled image and its corresponding RAG, draw the nodes and edges
of the RAG on the image with the specified colors. Nodes are marked by
the centroids of the corresponding regions.
Parameters
----------
labels : ndarray, shape (M, N)
The labelled image.
rag : RAG
The Region Adjacency Graph.
img : ndarray, shape (M, N, 3)
Input image.
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.
desaturate : bool, optional
Convert the image to grayscale before displaying. Particularly helps
visualization when using the `colormap` option.
in_place : bool, optional
If set, the RAG is modified in place. For each node `n` the function
will set a new attribute ``rag.node[n]['centroid']``.
Returns
-------
out : ndarray, shape (M, N, 3)
The image with the RAG drawn.
Examples
--------
>>> from skimage import data, graph, segmentation
>>> img = data.coffee()
>>> labels = segmentation.slic(img)
>>> g = graph.rag_mean_color(img, labels)
>>> out = graph.draw_rag(labels, g, img)
"""
if not in_place:
rag = rag.copy()
if desaturate:
img = color.rgb2gray(img)
img = color.gray2rgb(img)
out = util.img_as_float(img, force_copy=True)
cc = colors.ColorConverter()
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 label in d['labels']:
map_array[label] = offset
offset += 1
rag_labels = map_array[labels]
regions = measure.regionprops(rag_labels)
for (n, data), region in zip(rag.nodes_iter(data=True), regions):
data['centroid'] = region['centroid']
if border_color is not None:
border_color = cc.to_rgb(border_color)
out = segmentation.mark_boundaries(out, rag_labels, color=border_color)
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):
if data['weight'] >= thresh:
continue
r1, c1 = map(int, rag.node[n1]['centroid'])
r2, c2 = map(int, rag.node[n2]['centroid'])
line = draw.line(r1, c1, r2, c2)
if colormap is not None:
out[line] = smap.to_rgba([data['weight']])[0][:-1]
else:
out[line] = edge_color
circle = draw.circle(r1, c1, 2)
out[circle] = node_color
return out