elegant-scipy / elegant-scipy-submissions

Submissions of code snippets for the book Elegant SciPy
13 stars 2 forks source link

Create a region adjacency graph from an n-dimensional image #2

Closed jni closed 8 years ago

jni commented 9 years ago

Code by @vighneshbirodkar Submitted by @jni

A region adjacency graph (RAG) is a network abstraction of a set of image regions: every node in the network represents a region in the image, and nodes are connected when their corresponding regions touch in the image.

Using scipy.ndimage.generic_filter, we can create a RAG implemented in NetworkX for images of arbitrary dimensions (rather than just 2D images):

# input: labels, image

import numpy as nd
from scipy import ndimage as nd
import networkx as nx

def _add_edge_filter(values, g):
    """Add an edge between first element in `values` and
    all other elements of `values` in the graph `g`.
    `values[0]` is expected to be the central value of
    the footprint used.

    Parameters
    ----------
    values : array
        The array to process.
    g : RAG
        The graph to add edges in.

    Returns
    -------
    0.0 : float
        Always returns 0.

    """
    values = values.astype(int)
    current = values[0]
    for value in values[1:]:
        g.add_edge(current, value)
    return 0.0

# footprint for the filter
fp = np.array([[0, 0, 0],
               [0, 1, 1],
               [0, 1, 0]], np.uint8)

g = nx.Graph()

# run the add-edge filter on the regions
nd.generic_filter(labels,
                  function=_add_edge_filter,
                  footprint=fp,
                  mode='nearest',
                  extra_arguments=(g,))

# update the region properties using the image
for index in np.ndindex(labels.shape):
    current = labels[index]
    g.node[current]['pixel count'] += 1
    g.node[current]['total color'] += image[index]
hdashnow commented 8 years ago

@vighneshbirodkar this code is in :)