ENH using union find from morphology module

This commit is contained in:
Andreas Mueller
2012-06-16 17:28:43 +02:00
parent 967eb5b50d
commit e2d60f0135
5 changed files with 48 additions and 14 deletions
+10
View File
@@ -0,0 +1,10 @@
"""Export fast union find in Cython"""
cimport numpy as np
DTYPE = np.int
ctypedef np.int_t DTYPE_t
cdef DTYPE_t find_root(np.int_t *forest, np.int_t n)
cdef set_root(np.int_t *forest, np.int_t n, np.int_t root)
cdef join_trees(np.int_t *forest, np.int_t n, np.int_t m)
cdef link_bg(np.int_t *forest, np.int_t n, np.int_t *background_node)
-4
View File
@@ -1,4 +0,0 @@
# Implements Felsenzwalb's efficient graph based image segmentation.
# Author: Andreas Mueller
def felsenzwalb(np.ndarray[dtype=
@@ -1,10 +1,11 @@
import numpy as np
cimport numpy as np
from collections import defaultdict
import scipy
#from ..util import img_as_float
#from ..color import rgb2grey
from .union_find import UnionFind
from skimage.morphology.ccomp cimport find_root, join_trees
from IPython.core.debugger import Tracer
tracer = Tracer()
@@ -37,24 +38,23 @@ def felzenszwalb_segmentation(image, k, sigma=0.8):
# initialize data structures for segment size
# and inner cost, then start greedy iteration over edges.
edge_queue = np.argsort(costs)
segments = UnionFind()
cdef np.ndarray[np.int_t, ndim=2] segments = indices.reshape(width, height)
cdef np.int_t *segments_p = <np.int_t*>segments.data
cdef np.int_t seg_new
segment_size = defaultdict(lambda: 1)
# inner cost of segments
cint = defaultdict(lambda: 0)
for edge, cost in zip(edges[edge_queue], costs[edge_queue]):
seg0 = segments[edge[0]]
seg1 = segments[edge[1]]
seg0 = find_root(segments_p, edge[0])
seg1 = find_root(segments_p, edge[1])
if seg0 == seg1:
continue
inner_cost0 = cint[seg0] + k / segment_size[seg0]
inner_cost1 = cint[seg1] + k / segment_size[seg1]
if cost < min(inner_cost0, inner_cost1):
seg_new = segments.union(seg0, seg1)
# update size and cost
join_trees(segments_p, seg0, seg1)
seg_new = find_root(segments_p, seg0)
segment_size[seg_new] = segment_size[seg0] + segment_size[seg1]
cint[seg_new] = cost
out = np.zeros(width * height, dtype=np.int)
for i in xrange(width * height):
out[i] = segments[i]
out = out.reshape(width, height)
return out
return segments
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env python
import os
from skimage._build import cython
base_path = os.path.abspath(os.path.dirname(__file__))
def configuration(parent_package='', top_path=None):
from numpy.distutils.misc_util import Configuration, get_numpy_include_dirs
config = Configuration('segmentation', parent_package, top_path)
cython(['felzenszwalb.pyx'], working_path=base_path)
config.add_extension('felzenszwalb', sources=['felzenszwalb.c'],
include_dirs=[get_numpy_include_dirs()])
return config
if __name__ == '__main__':
from numpy.distutils.core import setup
setup(maintainer = 'scikits-image Developers',
maintainer_email = 'scikits-image@googlegroups.com',
description = 'Segmentation Algorithms',
url = 'https://github.com/scikits-image/scikits-image',
license = 'SciPy License (BSD Style)',
**(configuration(top_path='').todict())
)
+1
View File
@@ -17,6 +17,7 @@ def configuration(parent_package='', top_path=None):
config.add_subpackage('morphology')
config.add_subpackage('transform')
config.add_subpackage('util')
config.add_subpackage('segmentation')
def add_test_directories(arg, dirname, fnames):
if dirname.split(os.path.sep)[-1] == 'tests':