rebase and change API to support mpl colorspec

This commit is contained in:
Vighnesh Birodkar
2014-08-15 14:10:37 +05:30
parent 78caebf6d2
commit 4005749a61
3 changed files with 56 additions and 48 deletions
+7 -6
View File
@@ -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.")
+2
View File
@@ -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']
+47 -42
View File
@@ -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