Repository: scikit-image/scikit-image

Issue:
Deprecate guess_spatial_dimensions
As discussed in #3394, ``color.guess_spatial_dimensions`` is only used in one function ``gaussian.filter``. In addition, this function has a "magics" taste that we decided to limit in the future. #3394 proposed to move the useful code of ``guess_spatial_dimensions`` to the ``_gaussian.py`` module.



Discussion:

Resolving patch:
diff --git a/skimage/color/colorconv.py b/skimage/color/colorconv.py
--- a/skimage/color/colorconv.py
+++ b/skimage/color/colorconv.py
@@ -75,16 +75,9 @@ def guess_spatial_dimensions(image):
     ValueError
         If the image array has less than two or more than four dimensions.
     """
-    if image.ndim == 2:
-        return 2
-    if image.ndim == 3 and image.shape[-1] != 3:
-        return 3
-    if image.ndim == 3 and image.shape[-1] == 3:
-        return None
-    if image.ndim == 4 and image.shape[-1] == 3:
-        return 3
-    else:
-        raise ValueError("Expected 2D, 3D, or 4D array, got %iD." % image.ndim)
+    from ..filters import _guess_spatial_dimensions
+    warn('This function is deprecated and will be removed in 0.18', stacklevel=2)
+    return _guess_spatial_dimensions(image)
 
 
 def convert_colorspace(arr, fromspace, tospace):
diff --git a/skimage/filters/__init__.py b/skimage/filters/__init__.py
--- a/skimage/filters/__init__.py
+++ b/skimage/filters/__init__.py
@@ -1,5 +1,5 @@
 from .lpi_filter import inverse, wiener, LPIFilter2D
-from ._gaussian import gaussian
+from ._gaussian import gaussian, _guess_spatial_dimensions
 from .edges import (sobel, sobel_h, sobel_v,
                     scharr, scharr_h, scharr_v,
                     prewitt, prewitt_h, prewitt_v,
diff --git a/skimage/filters/_gaussian.py b/skimage/filters/_gaussian.py
--- a/skimage/filters/_gaussian.py
+++ b/skimage/filters/_gaussian.py
@@ -3,7 +3,6 @@
 from scipy import ndimage as ndi
 
 from ..util import img_as_float
-from ..color import guess_spatial_dimensions
 from .._shared.utils import warn, convert_to_float
 
 
@@ -96,7 +95,7 @@ def gaussian(image, sigma=1, output=None, mode='nearest', cval=0,
 
     spatial_dims = None
     try:
-        spatial_dims = guess_spatial_dimensions(image)
+        spatial_dims = _guess_spatial_dimensions(image)
     except ValueError:
         spatial_dims = image.ndim
     if spatial_dims is None and multichannel is None:
@@ -116,3 +115,34 @@ def gaussian(image, sigma=1, output=None, mode='nearest', cval=0,
     image = convert_to_float(image, preserve_range)
     return ndi.gaussian_filter(image, sigma, mode=mode, cval=cval,
                                truncate=truncate)
+
+
+def _guess_spatial_dimensions(image):
+    """Make an educated guess about whether an image has a channels dimension.
+
+    Parameters
+    ----------
+    image : ndarray
+        The input image.
+
+    Returns
+    -------
+    spatial_dims : int or None
+        The number of spatial dimensions of `image`. If ambiguous, the value
+        is ``None``.
+
+    Raises
+    ------
+    ValueError
+        If the image array has less than two or more than four dimensions.
+    """
+    if image.ndim == 2:
+        return 2
+    if image.ndim == 3 and image.shape[-1] != 3:
+        return 3
+    if image.ndim == 3 and image.shape[-1] == 3:
+        return None
+    if image.ndim == 4 and image.shape[-1] == 3:
+        return 3
+    else:
+        raise ValueError("Expected 2D, 3D, or 4D array, got %iD." % image.ndim)


Test patch:
diff --git a/skimage/color/tests/test_colorconv.py b/skimage/color/tests/test_colorconv.py
--- a/skimage/color/tests/test_colorconv.py
+++ b/skimage/color/tests/test_colorconv.py
@@ -35,29 +35,13 @@
                            rgb2ypbpr, ypbpr2rgb,
                            rgb2ycbcr, ycbcr2rgb,
                            rgb2ydbdr, ydbdr2rgb,
-                           rgba2rgb,
-                           guess_spatial_dimensions)
+                           rgba2rgb)
 
 from skimage import data_dir
 from skimage._shared._warnings import expected_warnings
-from skimage._shared import testing
 import colorsys
 
 
-def test_guess_spatial_dimensions():
-    im1 = np.zeros((5, 5))
-    im2 = np.zeros((5, 5, 5))
-    im3 = np.zeros((5, 5, 3))
-    im4 = np.zeros((5, 5, 5, 3))
-    im5 = np.zeros((5,))
-    assert_equal(guess_spatial_dimensions(im1), 2)
-    assert_equal(guess_spatial_dimensions(im2), 3)
-    assert_equal(guess_spatial_dimensions(im3), None)
-    assert_equal(guess_spatial_dimensions(im4), 3)
-    with testing.raises(ValueError):
-        guess_spatial_dimensions(im5)
-
-
 class TestColorconv(TestCase):
 
     img_rgb = imread(os.path.join(data_dir, 'color.png'))
diff --git a/skimage/filters/tests/test_gaussian.py b/skimage/filters/tests/test_gaussian.py
--- a/skimage/filters/tests/test_gaussian.py
+++ b/skimage/filters/tests/test_gaussian.py
@@ -1,5 +1,5 @@
 import numpy as np
-from skimage.filters._gaussian import gaussian
+from skimage.filters._gaussian import gaussian, _guess_spatial_dimensions
 from skimage._shared import testing
 from skimage._shared._warnings import expected_warnings
 
@@ -68,3 +68,17 @@ def test_4d_ok():
     img[2, 2, 2, 2] = 1
     res = gaussian(img, 1, mode='reflect')
     assert np.allclose(res.sum(), 1)
+
+
+def test_guess_spatial_dimensions():
+    im1 = np.zeros((5, 5))
+    im2 = np.zeros((5, 5, 5))
+    im3 = np.zeros((5, 5, 3))
+    im4 = np.zeros((5, 5, 5, 3))
+    im5 = np.zeros((5,))
+    testing.assert_equal(_guess_spatial_dimensions(im1), 2)
+    testing.assert_equal(_guess_spatial_dimensions(im2), 3)
+    testing.assert_equal(_guess_spatial_dimensions(im3), None)
+    testing.assert_equal(_guess_spatial_dimensions(im4), 3)
+    with testing.raises(ValueError):
+        _guess_spatial_dimensions(im5)