From 610a0d1793f1b3fb91544c1921311ecf20ff355d Mon Sep 17 00:00:00 2001 From: Juan Nunez-Iglesias Date: Mon, 16 Sep 2013 17:49:07 +1000 Subject: [PATCH] Add support for list sigma input in SLIC Previously, having a different `sigma` for different dimensions required an array input. This allows the user to use a simple list, which gets converted to an array internally. Importantly, it removes a very unhelpful error: ```python >>> im = np.random.rand(10, 20) >>> from skimage import segmentation as seg Exception AttributeError: "'UmfpackContext' object has no attribute '_symbolic'" in > ignored >>> s = seg.slic(im, 2, sigma=[2, 1]) --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) in () ----> 1 s = seg.slic(im, 2, sigma=[2, 1]) /Users/nuneziglesiasj/venv/skimdev2/lib/python2.7/site-packages/scikit_image-0.9dev-py2.7-macosx-10.5-x86_64.egg/skimage/segmentation/slic_superpixels.pyc in slic(image, n_segments, compactness, max_iter, sigma, multichannel, convert2lab, ratio) 106 if not isinstance(sigma, coll.Iterable): 107 sigma = np.array([sigma, sigma, sigma]) --> 108 if (sigma > 0).any(): 109 sigma = list(sigma) + [0] 110 image = ndimage.gaussian_filter(image, sigma) AttributeError: 'bool' object has no attribute 'any' ``` --- skimage/segmentation/slic_superpixels.py | 6 ++++-- skimage/segmentation/tests/test_slic.py | 11 +++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/skimage/segmentation/slic_superpixels.py b/skimage/segmentation/slic_superpixels.py index 08ea7126..be07fafe 100644 --- a/skimage/segmentation/slic_superpixels.py +++ b/skimage/segmentation/slic_superpixels.py @@ -27,7 +27,7 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=None, infinity, superpixel shapes become square/cubic. max_iter : int, optional Maximum number of iterations of k-means. - sigma : float or (3,) array of floats, optional + sigma : float or (3,) array-like of floats, optional Width of Gaussian smoothing kernel for pre-processing for each dimension of the image. The same sigma is applied to each dimension in case of a scalar value. Zero means no smoothing. @@ -104,7 +104,9 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=None, image = image[..., np.newaxis] if not isinstance(sigma, coll.Iterable): - sigma = np.array([sigma, sigma, sigma]) + sigma = np.array([sigma, sigma, sigma], float) + elif type(sigma) in [list, tuple]: + sigma = np.array(sigma, float) if (sigma > 0).any(): sigma = list(sigma) + [0] image = ndimage.gaussian_filter(image, sigma) diff --git a/skimage/segmentation/tests/test_slic.py b/skimage/segmentation/tests/test_slic.py index 6d00716f..2a190de8 100644 --- a/skimage/segmentation/tests/test_slic.py +++ b/skimage/segmentation/tests/test_slic.py @@ -90,6 +90,17 @@ def test_gray_3d(): assert_array_equal(seg[s], c) +def test_list_sigma(): + rnd = np.random.RandomState(0) + img = np.array([[1, 1, 1, 0, 0, 0], + [0, 0, 0, 1, 1, 1]], np.float) + img += 0.1 * rnd.normal(size=img.shape) + result_sigma = np.array([[0, 0, 0, 1, 1, 1], + [0, 0, 0, 1, 1, 1]], np.int) + seg_sigma = slic(img, n_segments=2, sigma=[1, 50, 1], multichannel=False) + assert_equal(seg_sigma, result_sigma) + + if __name__ == '__main__': from numpy import testing testing.run_module_suite()