From f5f93f8ce32b53b24c1ec1d76692a60b5ac86f8d Mon Sep 17 00:00:00 2001 From: Vighnesh Birodkar Date: Wed, 18 Jun 2014 03:53:33 +0530 Subject: [PATCH] Removed cython file and added nd python function for RAG construction --- skimage/graph/_build_rag.pyx | 166 ----------------------------------- skimage/graph/rag.py | 65 +++++++++++--- skimage/graph/setup.py | 4 - 3 files changed, 54 insertions(+), 181 deletions(-) delete mode 100644 skimage/graph/_build_rag.pyx diff --git a/skimage/graph/_build_rag.pyx b/skimage/graph/_build_rag.pyx deleted file mode 100644 index e6825c9d..00000000 --- a/skimage/graph/_build_rag.pyx +++ /dev/null @@ -1,166 +0,0 @@ -import numpy as np -cimport numpy as cnp -import rag - - -def construct_rag_meancolor_3d(img, arr): - """Computes the Region Adjacency Graph of a 3D color image using - difference in mean color of regions as edge weights. - - Given an image and its segmentation, this method constructs the - corresponsing Region Adjacency Graph (RAG). Each node in the RAG - represents contiguous pixels with in `img` with the same label in - `arr`. There is an edge between each pair of adjacent regions. - - Parameters - ---------- - img : (width, height, depth, 3) ndarray - Input image. - arr : (width, height, depth) ndarray - The array with labels. - - Returns - ------- - out : RAG - The region adjacency graph. - """ - - cdef Py_ssize_t depth,width,height, i, j, k - cdef cnp.int32_t current, next - width = arr.shape[0] - height = arr.shape[1] - depth = arr.shape[2] - - g = rag.RAG() - - i = 0 - for i in range(width-1): - j = 0 - for j in range(height-1): - k = 0 - for k in range(depth-1): - current = arr[i, j, k] - - try: - g.node[current]['pixel count'] += 1 - g.node[current]['total color'] += img[i, j] - except KeyError: - g.add_node(current) - g.node[current]['pixel count'] = 1 - g.node[current]['total color'] = img[i, j].astype(np.long) - g.node[current]['labels'] = [arr[i, j]] - - next = arr[i + 1, j, k] - if current != next: - g.add_edge(current, next) - - next = arr[i, j + 1, k] - if current != next: - g.add_edge(current, next) - - next = arr[i + 1, j + 1, k] - if current != next: - g.add_edge(current, next) - - next = arr[i + 1, j, k + 1] - if current != next: - g.add_edge(current, next) - - next = arr[i, j + 1, k + 1] - if current != next: - g.add_edge(current, next) - - next = arr[i + 1, j + 1, k + 1] - if current != next: - g.add_edge(current, next) - - next = arr[i, j, k + 1] - if current != next: - g.add_edge(current, next) - - k += 1 - - j += 1 - - i += 1 - - for n in g.nodes(): - g.node[n]['mean color'] = g.node[n][ - 'total color'] / g.node[n]['pixel count'] - - for x, y in g.edges_iter(): - diff = g.node[x]['mean color'] - g.node[y]['mean color'] - g[x][y]['weight'] = np.linalg.norm(diff) - - return g - - -def construct_rag_meancolor_2d(img, arr): - """Computes the Region Adjacency Graph of a 2D color image using - difference in mean color of regions as edge weights. - - Given an image and its segmentation, this method constructs the - corresponsing Region Adjacency Graph (RAG). Each node in the RAG - represents contiguous pixels with in `img` with the same label in - `arr`. There is an edge between each pair of adjacent regions. - - Parameters - ---------- - img : (width, height, 3) ndarray - Input image. - arr : (width, height) ndarray - The array with labels. - - Returns - ------- - out : RAG - The region adjacency graph. - """ - - cdef Py_ssize_t width, height, h, i, j, k - cdef cnp.int32_t current, next - width = arr.shape[0] - height = arr.shape[1] - - g = rag.RAG() - - i = 0 - for i in range(width-1): - j = 0 - for j in range(height-1): - current = arr[i, j] - - try: - g.node[current]['pixel count'] += 1 - g.node[current]['total color'] += img[i, j] - except KeyError: - g.add_node(current) - g.node[current]['pixel count'] = 1 - g.node[current]['total color'] = img[i, j].astype(np.long) - g.node[current]['labels'] = [arr[i, j]] - - next = arr[i + 1, j] - if current != next: - g.add_edge(current, next) - - next = arr[i, j + 1] - if current != next: - g.add_edge(current, next) - - next = arr[i + 1, j + 1] - if current != next: - g.add_edge(current, next) - - j += 1 - - i += 1 - - for n in g.nodes(): - g.node[n]['mean color'] = g.node[n][ - 'total color'] / g.node[n]['pixel count'] - - for x, y in g.edges_iter(): - diff = g.node[x]['mean color'] - g.node[y]['mean color'] - g[x][y]['weight'] = np.linalg.norm(diff) - - return g diff --git a/skimage/graph/rag.py b/skimage/graph/rag.py index 72befba9..92231280 100644 --- a/skimage/graph/rag.py +++ b/skimage/graph/rag.py @@ -1,7 +1,7 @@ import networkx as nx -from skimage import util -from ._build_rag import construct_rag_meancolor_2d -from ._build_rag import construct_rag_meancolor_3d +from . import rag +import numpy as np +from scipy.ndimage import filters class RAG(nx.Graph): @@ -49,7 +49,18 @@ class RAG(nx.Graph): self.remove_node(i) -def rag_meancolor(img, labels): +def _add_edge(values, g): + values = values.astype(int) + current = values[0] + + for value in values[1:]: + if value >= 0: + g.add_edge(current, value) + + return 0.0 + + +def rag_mean_color(img, arr): """Computes the Region Adjacency Graph of a color image using difference in mean color of regions as edge weights. @@ -78,11 +89,43 @@ def rag_meancolor(img, labels): >>> rag = graph.rag_meancolor(img, labels) """ + g = rag.RAG() - img = util.img_as_ubyte(img) - if img.ndim == 4: - return construct_rag_meancolor_3d(img, labels) - elif img.ndim == 3: - return construct_rag_meancolor_2d(img, labels) - else: - raise ValueError("Image dimension not supported") + fp = np.zeros((3,) * arr.ndim) + slc = slice(1, None, None) + fp[(slc,) * arr.ndim] = 1 + + filters.generic_filter( + arr, + function=_add_edge, + footprint=fp, + mode='constant', + cval=-1, + extra_arguments=(g, + )) + iter = np.nditer(arr, flags=['multi_index']) + + while not iter.finished: + + current = arr[iter.multi_index] + try: + g.node[current]['pixel count'] += 1 + g.node[current]['total color'] += img[iter.multi_index] + except KeyError: + g.add_node(current) + g.node[current]['pixel count'] = 1 + g.node[current]['total color'] = img[ + iter.multi_index].astype(np.long) + g.node[current]['labels'] = [arr[iter.multi_index]] + + iter.iternext() + + for n in g.nodes(): + g.node[n]['mean color'] = g.node[n][ + 'total color'] / g.node[n]['pixel count'] + + for x, y in g.edges_iter(): + diff = g.node[x]['mean color'] - g.node[y]['mean color'] + g[x][y]['weight'] = np.linalg.norm(diff) + + return g diff --git a/skimage/graph/setup.py b/skimage/graph/setup.py index 436029da..45dd205a 100644 --- a/skimage/graph/setup.py +++ b/skimage/graph/setup.py @@ -17,8 +17,6 @@ def configuration(parent_package='', top_path=None): cython(['_spath.pyx'], working_path=base_path) cython(['_mcp.pyx'], working_path=base_path) cython(['heap.pyx'], working_path=base_path) - cython(['_build_rag.pyx'], working_path=base_path) - config.add_extension('_spath', sources=['_spath.c'], include_dirs=[get_numpy_include_dirs()]) @@ -26,8 +24,6 @@ def configuration(parent_package='', top_path=None): include_dirs=[get_numpy_include_dirs()]) config.add_extension('heap', sources=['heap.c'], include_dirs=[get_numpy_include_dirs()]) - config.add_extension('_build_rag', sources=['_build_rag.c'], - include_dirs=[get_numpy_include_dirs()]) return config