diff --git a/skimage/segmentation/_slic.pyx b/skimage/segmentation/_slic.pyx index 86654b11..6faaa69b 100644 --- a/skimage/segmentation/_slic.pyx +++ b/skimage/segmentation/_slic.pyx @@ -11,27 +11,18 @@ from skimage.util import regular_grid def _slic_cython(double[:, :, :, ::1] image_zyx, - Py_ssize_t[:, :, ::1] nearest_clusters, - double[:, :, ::1] distance, double[:, ::1] clusters, - Py_ssize_t max_iter, Py_ssize_t n_segments): + Py_ssize_t max_iter): """Helper function for SLIC segmentation. Parameters ---------- image_zyx : 4D array of double, shape (Z, Y, X, C) - The image with embedded coordinates, that is, `image_zyx[i, j, k]` is - `array([i, j, k, c])`, depending on the colorspace. - nearest_clusters : 3D array of int, shape (Z, Y, X) - The (initially empty) label field. - distance : 3D array of double, shape (Z, Y, X) - The (initially infinity) array of distances to the nearest centroid. - clusters : 2D array of double, shape (n_segments, 3 + C) - The centroids obtained by SLIC. + The input image. + clusters : 2D array of double, shape (N, 3 + C) + The initial centroids obtained by SLIC as [Z, Y, X, C...]. max_iter : int The maximum number of k-means iterations. - n_segments : int - The approximate/desired number of segments. Returns ------- @@ -39,7 +30,7 @@ def _slic_cython(double[:, :, :, ::1] image_zyx, The label field/superpixels found by SLIC. """ - # initialize on grid: + # initialize on grid cdef Py_ssize_t depth, height, width depth, height, width = (image_zyx.shape[0], image_zyx.shape[1], image_zyx.shape[2]) @@ -50,9 +41,14 @@ def _slic_cython(double[:, :, :, ::1] image_zyx, # approximate grid size for desired n_segments cdef Py_ssize_t step_z, step_y, step_x - slices = regular_grid((depth, height, width), n_segments) + slices = regular_grid((depth, height, width), n_clusters) step_z, step_y, step_x = [int(s.step) for s in slices] + cdef Py_ssize_t[:, :, ::1] nearest_clusters \ + = np.empty((depth, height, width), dtype=np.intp) + cdef float[:, :, ::1] distance \ + = np.empty((depth, height, width), dtype=np.float32) + cdef Py_ssize_t i, c, k, x, y, z, x_min, x_max, y_min, y_max, z_min, \ z_max cdef double dist_mean diff --git a/skimage/segmentation/slic_superpixels.py b/skimage/segmentation/slic_superpixels.py index 1db2754a..42d30593 100644 --- a/skimage/segmentation/slic_superpixels.py +++ b/skimage/segmentation/slic_superpixels.py @@ -44,7 +44,7 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=1, Returns ------- - segment_mask : (width, height, depth) array + labels : (width, height, depth) array Integer mask indicating segment labels. Raises @@ -82,6 +82,7 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=1, >>> # Increasing the ratio parameter yields more square regions >>> segments = slic(img, n_segments=100, ratio=20) """ + if ratio is not None: msg = 'Keyword `ratio` is deprecated. Use `compactness` instead.' warnings.warn(msg) @@ -115,10 +116,9 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=1, if image.shape[3] == 3 and convert2lab: image = rgb2lab(image) - # initialize on grid depth, height, width = image.shape[:3] - # approximate grid size for desired n_segments + # initialize cluster centroids for desired number of segments grid_z, grid_y, grid_x = np.mgrid[:depth, :height, :width] slices = regular_grid(image.shape[:3], n_segments) step_z, step_y, step_x = [int(s.step) for s in slices] @@ -139,13 +139,9 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=1, ratio = float(max((step_z, step_y, step_x))) / compactness image = image * ratio - nearest_cluster = np.empty((depth, height, width), dtype=np.intp) - distance = np.empty((depth, height, width), dtype=np.float) + labels = _slic_cython(image, clusters, max_iter) - segment_map = _slic_cython(image, nearest_cluster, distance, clusters, - max_iter, n_segments) + if labels.shape[0] == 1: + labels = labels[0] - if segment_map.shape[0] == 1: - segment_map = segment_map[0] - - return segment_map + return labels