mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-10 03:14:55 +08:00
added boundary rag construction
This commit is contained in:
committed by
Vighnesh Birodkar
parent
8f2839e1b3
commit
1769cdddcf
@@ -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()
|
||||
@@ -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']
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user