diff --git a/skimage/segmentation/quickshift.py b/skimage/segmentation/quickshift.pyx similarity index 77% rename from skimage/segmentation/quickshift.py rename to skimage/segmentation/quickshift.pyx index 65c8847f..8bec6d2b 100644 --- a/skimage/segmentation/quickshift.py +++ b/skimage/segmentation/quickshift.pyx @@ -1,8 +1,10 @@ import numpy as np +cimport numpy as np + from itertools import product -def quickshift(image, sigma=5, tau=10): +def quickshift(np.ndarray[dtype=np.float_t, ndim=3, mode="c"] image, sigma=5, tau=10): """Computes quickshift clustering in RGB-(x,y) space. Parameters @@ -31,37 +33,38 @@ def quickshift(image, sigma=5, tau=10): # window size for neighboring pixels to consider if sigma < 1: raise ValueError("Sigma should be >= 1") - w = int(2 * sigma) + cdef int w = int(2 * sigma) + + cdef int width = image.shape[0] + cdef int height = image.shape[1] - width, height = image.shape[:2] - densities = np.zeros((width, height)) + cdef np.ndarray[dtype=np.float_t, ndim=2] densities = np.zeros((width, height)) # compute densities for x, y in product(xrange(width), xrange(height)): - current_pixel = np.hstack([image[x, y, :], x, y]) + current_pixel = image[x, y, :] for xx, yy in product(xrange(-w / 2, w / 2 + 1), repeat=2): x_, y_ = x + xx, y + yy if 0 <= x_ < width and 0 <= y_ < height: - other_pixel = np.hstack([image[x_, y_, :], x_, y_]) - dist = np.sum((current_pixel - other_pixel) ** 2) + dist = np.sum((current_pixel - image[x_, y_, :])**2) + (x - x_)**2 + (y - y_)**2 densities[x, y] += np.exp(-dist / sigma) # this will break ties that otherwise would give us headache - densities += np.random.normal(scale=0.00001, size=densities.shape) + + densities += np.random.normal(scale=0.00001, size=(width, height)) # default parent to self: parent = np.arange(width * height).reshape(width, height) dist_parent = np.zeros((width, height)) # find nearest node with higher density for x, y in product(xrange(width), xrange(height)): current_density = densities[x, y] - current_pixel = np.hstack([image[x, y, :], x, y]) + current_pixel = image[x, y, :] closest = np.inf for xx, yy in product(xrange(-w / 2, w / 2 + 1), repeat=2): x_, y_ = x + xx, y + yy if 0 <= x_ < width and 0 <= y_ < height: if densities[x_, y_] > current_density: - other_pixel = np.hstack([image[x_, y_, :], x_, y_]) - dist = np.sum((current_pixel - other_pixel) ** 2) + dist = np.sum((current_pixel - image[x_, y_, :])**2) + (x - x_)**2 + (y - y_)**2 if dist < closest: closest = dist parent[x, y] = x_ * width + y_ diff --git a/skimage/segmentation/setup.py b/skimage/segmentation/setup.py index 8f6361bf..b6f8d1e2 100644 --- a/skimage/segmentation/setup.py +++ b/skimage/segmentation/setup.py @@ -5,23 +5,27 @@ 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'], + #cython(['felzenszwalb.pyx'], working_path=base_path) + #config.add_extension('felzenszwalb', sources=['felzenszwalb.c'], + #include_dirs=[get_numpy_include_dirs()]) + cython(['quickshift.pyx'], working_path=base_path) + config.add_extension('quickshift', sources=['quickshift.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)', + 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()) )