mirror of
https://github.com/wassname/scikit-image.git
synced 2026-08-03 13:11:25 +08:00
Merged the separate loops for SLIC-zero and SLIC into one, and some minor improvements based on feedback on Github.
This commit is contained in:
@@ -10,12 +10,13 @@ cimport numpy as cnp
|
||||
|
||||
from skimage.util import regular_grid
|
||||
|
||||
|
||||
def _slic_cython(double[:, :, :, ::1] image_zyx,
|
||||
double[:, ::1] segments,
|
||||
float step,
|
||||
Py_ssize_t max_iter,
|
||||
double[::1] spacing,
|
||||
bool slic_zero,
|
||||
bint slic_zero,
|
||||
):
|
||||
"""Helper function for SLIC segmentation.
|
||||
|
||||
@@ -36,7 +37,6 @@ def _slic_cython(double[:, :, :, ::1] image_zyx,
|
||||
slic_zero : bool
|
||||
True to run SLIC-zero, False to run original SLIC.
|
||||
|
||||
|
||||
Returns
|
||||
-------
|
||||
nearest_segments : 3D array of int, shape (Z, Y, X)
|
||||
@@ -122,42 +122,25 @@ def _slic_cython(double[:, :, :, ::1] image_zyx,
|
||||
x_min = <Py_ssize_t>max(cx - 2 * step_x, 0)
|
||||
x_max = <Py_ssize_t>min(cx + 2 * step_x + 1, width)
|
||||
|
||||
# The loop is duplicated to avoid looking up slic_zero in every
|
||||
# iteration but perhaps it's better to improve readability at
|
||||
# the cost of performance.
|
||||
if slic_zero:
|
||||
for z in range(z_min, z_max):
|
||||
dz = (sz * (cz - z)) ** 2
|
||||
for y in range(y_min, y_max):
|
||||
dy = (sy * (cy - y)) ** 2
|
||||
for x in range(x_min, x_max):
|
||||
dist_center = (dz + dy + (sx * (cx - x)) ** 2) * zyx_wt
|
||||
dist_color = 0
|
||||
for c in range(3, n_features):
|
||||
dist_color += (image_zyx[z, y, x, c - 3]
|
||||
- segments[k, c]) ** 2
|
||||
|
||||
for z in range(z_min, z_max):
|
||||
dz = (sz * (cz - z)) ** 2
|
||||
for y in range(y_min, y_max):
|
||||
dy = (sy * (cy - y)) ** 2
|
||||
for x in range(x_min, x_max):
|
||||
dist_center = (dz + dy + (sx * (cx - x)) ** 2) * zyx_wt
|
||||
dist_color = 0
|
||||
for c in range(3, n_features):
|
||||
dist_color += (image_zyx[z, y, x, c - 3]
|
||||
- segments[k, c]) ** 2
|
||||
if slic_zero:
|
||||
dist_center += dist_color / max_dist_color[k]
|
||||
else:
|
||||
dist_center += dist_color
|
||||
|
||||
if distance[z, y, x] > dist_center:
|
||||
nearest_segments[z, y, x] = k
|
||||
distance[z, y, x] = dist_center
|
||||
change = 1
|
||||
else:
|
||||
for z in range(z_min, z_max):
|
||||
dz = (sz * (cz - z)) ** 2
|
||||
for y in range(y_min, y_max):
|
||||
dy = (sy * (cy - y)) ** 2
|
||||
for x in range(x_min, x_max):
|
||||
dist_center = (dz + dy + (sx * (cx - x)) ** 2) * zyx_wt
|
||||
for c in range(3, n_features):
|
||||
dist_center += (image_zyx[z, y, x, c - 3]
|
||||
- segments[k, c]) ** 2
|
||||
|
||||
if distance[z, y, x] > dist_center:
|
||||
nearest_segments[z, y, x] = k
|
||||
distance[z, y, x] = dist_center
|
||||
change = 1
|
||||
if distance[z, y, x] > dist_center:
|
||||
nearest_segments[z, y, x] = k
|
||||
distance[z, y, x] = dist_center
|
||||
change = 1
|
||||
|
||||
# stop if no pixel changed its segment
|
||||
if change == 0:
|
||||
|
||||
@@ -12,7 +12,8 @@ from skimage.color import rgb2lab
|
||||
|
||||
def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=None,
|
||||
spacing=None, multichannel=True, convert2lab=True, ratio=None,
|
||||
enforce_connectivity=False, min_size_factor=0.5, max_size_factor=3):
|
||||
enforce_connectivity=False, min_size_factor=0.5, max_size_factor=3,
|
||||
slic_zero=False):
|
||||
"""Segments image using k-means clustering in Color-(x,y,z) space.
|
||||
|
||||
Parameters
|
||||
@@ -47,8 +48,6 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=None,
|
||||
Whether the input should be converted to Lab colorspace prior to
|
||||
segmentation. For this purpose, the input is assumed to be RGB. Highly
|
||||
recommended.
|
||||
slic_zero: bool, optional
|
||||
True to run SLIC-zero, False to run original SLIC.
|
||||
ratio : float, optional
|
||||
Synonym for `compactness`. This keyword is deprecated.
|
||||
enforce_connectivity: bool, optional (default False)
|
||||
@@ -59,6 +58,8 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=None,
|
||||
max_size_factor: float, optional
|
||||
Proportion of the maximum connected segment size. A value of 3 works
|
||||
in most of the cases.
|
||||
slic_zero: bool, optional
|
||||
True to run SLIC-zero, False to run original SLIC.
|
||||
Returns
|
||||
-------
|
||||
labels : 2D or 3D array
|
||||
@@ -169,21 +170,19 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=None,
|
||||
segments_y[..., np.newaxis],
|
||||
segments_x[..., np.newaxis],
|
||||
segments_color
|
||||
], axis=-1).reshape(-1, 3 + image.shape[3])
|
||||
], axis=-1).reshape(-1, 3 + image.shape[3])
|
||||
segments = np.ascontiguousarray(segments)
|
||||
|
||||
# we do the scaling of ratio in the same way as in the SLIC paper
|
||||
# so the values have the same meaning
|
||||
step = float(max((step_z, step_y, step_x)))
|
||||
ratio = float(1) / compactness
|
||||
|
||||
ratio = 1.0 / compactness
|
||||
|
||||
if slic_zero:
|
||||
image = np.ascontiguousarray(image * ratio)
|
||||
else:
|
||||
image = np.ascontiguousarray(image * ratio)
|
||||
|
||||
# _slic_cython expects the image in zyx format... but isn't image in xyz
|
||||
# format???
|
||||
labels = _slic_cython(image, segments, step, max_iter, spacing, slic_zero)
|
||||
|
||||
if enforce_connectivity:
|
||||
@@ -198,4 +197,4 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=None,
|
||||
if is_2d:
|
||||
labels = labels[0]
|
||||
|
||||
return labels
|
||||
return labels
|
||||
|
||||
@@ -147,6 +147,7 @@ def test_enforce_connectivity():
|
||||
assert_equal(segments_connected, result_connected)
|
||||
assert_equal(segments_disconnected, result_disconnected)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from numpy import testing
|
||||
|
||||
|
||||
Reference in New Issue
Block a user