Repository: scikit-image/scikit-image

Issue:
type error for morphology.remove_small_objects()
Is it better to add type error for non-labeled int? 

``` python
a = np.array([[0, 0, 0, 1, 0],
    [1, 1, 1, 0, 0],
    [1, 1, 1, 0, 1]], int)

b = morphology.remove_small_objects(a, 6)

print b

[[0 0 0 1 0]
 [1 1 1 0 0]
 [1 1 1 0 1]]
```



Discussion:
@YZHANGFPE, but how do we know that it's not a labeled image with a single object?

Is your suggestion that if it _looks_ like a boolean array, we should treat it as such? I'd be ok with doing that, but generally in scikit-image we tend to shy away from "magic" in favour of predictable behaviour. In this case, you should just do .astype(bool) before you call our function.

@stefanv @ahojnnes do you guys have an opinion here?

Thanks for the reply. 

I didn't look into the low level code on how the labeled image differs from a regular int image but my intuition is that they are different because the function generate correct result for the labeled image but not for the regular int image. So if this difference is easily detectable, I would suggest raise a type error for that.

In this case, we cannot throw an error, but a warning may suffice?

Sure

@stefanv are you suggesting a warning + magic behaviour, or just a warning when there is a single labelled object? I'll note that the docstring [specifies](https://github.com/scikit-image/scikit-image/blob/master/skimage/morphology/misc.py#L61) that int images are assumed to be labelled already.

No magic behavior!  Just a warning if we detect that an array consists of
only 0's and 1's.


Resolving patch:
diff --git a/skimage/morphology/misc.py b/skimage/morphology/misc.py
--- a/skimage/morphology/misc.py
+++ b/skimage/morphology/misc.py
@@ -1,5 +1,6 @@
 import numpy as np
 import functools
+import warnings
 import scipy.ndimage as nd
 from .selem import _default_selem
 
@@ -128,6 +129,10 @@ def remove_small_objects(ar, min_size=64, connectivity=1, in_place=False):
                          "relabeling the input with `scipy.ndimage.label` or "
                          "`skimage.morphology.label`.")
 
+    if len(component_sizes) == 2:
+        warnings.warn("Only one label was provided to `remove_small_objects`. "
+                      "Did you mean to use a boolean array?")
+
     too_small = component_sizes < min_size
     too_small_mask = too_small[ccs]
     out[too_small_mask] = 0


Test patch:
diff --git a/skimage/morphology/tests/test_misc.py b/skimage/morphology/tests/test_misc.py
--- a/skimage/morphology/tests/test_misc.py
+++ b/skimage/morphology/tests/test_misc.py
@@ -1,5 +1,6 @@
 import numpy as np
-from numpy.testing import assert_array_equal, assert_equal, assert_raises
+from numpy.testing import (assert_array_equal, assert_equal, assert_raises,
+                           assert_warns)
 from skimage.morphology import remove_small_objects
 
 test_image = np.array([[0, 0, 0, 1, 0],
@@ -55,6 +56,13 @@ def test_uint_image():
     assert_array_equal(observed, expected)
 
 
+def test_single_label_warning():
+    image = np.array([[0, 0, 0, 1, 0],
+                      [1, 1, 1, 0, 0],
+                      [1, 1, 1, 0, 0]], int)
+    assert_warns(UserWarning, remove_small_objects, image, min_size=6)
+
+
 def test_float_input():
     float_test = np.random.rand(5, 5)
     assert_raises(TypeError, remove_small_objects, float_test)