diff --git a/skimage/segmentation/_slic.pyx b/skimage/segmentation/_slic.pyx index 57c9990a..3247dd79 100644 --- a/skimage/segmentation/_slic.pyx +++ b/skimage/segmentation/_slic.pyx @@ -25,6 +25,9 @@ def _slic_cython(double[:, :, :, ::1] image_zyx, max_iter : int The maximum number of k-means iterations. spacing : 1D array of double, shape (3,) + The voxel spacing along each image dimension. This parameter + controls the weights of the distances along z, y, and x during + k-means clustering. Returns ------- diff --git a/skimage/segmentation/slic_superpixels.py b/skimage/segmentation/slic_superpixels.py index e9ae8ee7..3cb67874 100644 --- a/skimage/segmentation/slic_superpixels.py +++ b/skimage/segmentation/slic_superpixels.py @@ -34,6 +34,8 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=None, spacing : (3,) array-like of floats, optional The voxel spacing along each image dimension. By default, `slic` assumes uniform spacing (same voxel resolution along z, y and x). + This parameter controls the weights of the distances along z, y, + and x during k-means clustering. multichannel : bool, optional Whether the last axis of the image is to be interpreted as multiple channels or another spatial dimension. @@ -61,6 +63,11 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=None, If `sigma > 0`, the image is smoothed using a Gaussian kernel prior to segmentation. + If `sigma > 0` and `spacing` is provided, the kernel width is divided + along each dimension by the spacing. For example, if `sigma=1` and + `spacing=[5, 1, 1]`, the effective `sigma` is `[0.2, 1, 1]`. This + ensures sensible smoothing for anisotropic images. + The image is rescaled to be in [0, 1] prior to processing. Images of shape (M, N, 3) are interpreted as 2D RGB images by default. To @@ -108,14 +115,14 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=None, if spacing is None: spacing = np.ones(3) - elif type(spacing) in [list, tuple]: - spacing = np.array(spacing, float) + elif isinstance(spacing, (list, tuple)): + spacing = np.array(spacing, np.double) if not isinstance(sigma, coll.Iterable): - sigma = np.array([sigma, sigma, sigma], float) - elif type(sigma) in [list, tuple]: - sigma = np.array(sigma, float) + sigma = np.array([sigma, sigma, sigma], np.double) + elif isinstance(spacing, (list, tuple)): + sigma = np.array(sigma, np.double) if (sigma > 0).any(): - sigma /= spacing.astype(float) + sigma /= spacing.astype(np.double) sigma = list(sigma) + [0] image = ndimage.gaussian_filter(image, sigma)