Repository: scikit-image/scikit-image

Issue:
skimage.transform.rescale fails for scale < 0.2
## Description

The function `skimage.transform.rescale` throws an error for for `scale < 0.2`, which is quite unexpected if you're just trying to use the `rescale` function. I get following error messages for these small scale factors:
```
SOME_PATH\skimage\transform\_warps.py:115: RuntimeWarning: divide by zero encountered in true_divide
  factors = (np.asarray(input_shape, dtype=float) /
Traceback (most recent call last):
  File "PATH_TO\my_script.py", line 5, in <module>
    img = transform.rescale(img, scale=0.1)  # error
  File "SOME_PATH\skimage\transform\_warps.py", line 290, in rescale
    return resize(image, output_shape, order=order, mode=mode, cval=cval,
  File "SOME_PATH\skimage\transform\_warps.py", line 147, in resize
    image = ndi.gaussian_filter(image, anti_aliasing_sigma,
  File "SOME_PATH\scipy\ndimage\filters.py", line 341, in gaussian_filter
    gaussian_filter1d(input, sigma, axis, order, output,
  File "SOME_PATH\scipy\ndimage\filters.py", line 257, in gaussian_filter1d
    lw = int(truncate * sd + 0.5)
OverflowError: cannot convert float infinity to integer
Process finished with exit code 1
```

## Way to reproduce
```python
from skimage import transform
import numpy as np
img = np.zeros((30, 40, 3))
img = transform.rescale(img, scale=0.2)  # ok
img = transform.rescale(img, scale=0.1)  # error
```


## Version information
```python
# Paste the output of the following python commands
from __future__ import print_function
import sys; print(sys.version)
import platform; print(platform.platform())
import skimage; print("scikit-image version: {}".format(skimage.__version__))
import numpy; print("numpy version: {}".format(numpy.__version__))
```

```python
3.7.3 (default, Mar 27 2019, 17:13:21) [MSC v.1915 64 bit (AMD64)]
Windows-10-10.0.19041-SP0
scikit-image version: 0.14.2
numpy version: 1.16.2
```




Discussion:
Thank you @pyscorcher for the report, I can reproduce the bug.

In the example that you provided, the input image shape is `(30, 40, 3)` and when you apply a scale factor of `0.1`, the output image shape is obtained as `round(0.1 * [30, 40, 3]) = round([3, 4, 0.3])`, which is `[3, 4, 0]`. This last 0 is the root of the problem.

I assume that this behavior is expected, but the raised error is extremely confusing :confused:.
Thanks for getting to the bottom of that @rfezzani 

@pyscorcher to help you with your work, there is a multichannel parameter that also exists in version 0.14.2 
https://scikit-image.org/docs/0.14.x/api/skimage.transform.html#rescale

I think that should help you. Let us know!

Resolving patch:
diff --git a/skimage/transform/_warps.py b/skimage/transform/_warps.py
--- a/skimage/transform/_warps.py
+++ b/skimage/transform/_warps.py
@@ -281,7 +281,7 @@ def rescale(image, scale, order=None, mode='reflect', cval=0, clip=True,
         if multichannel:
             scale = np.concatenate((scale, [1]))
     orig_shape = np.asarray(image.shape)
-    output_shape = np.round(scale * orig_shape)
+    output_shape = np.maximum(np.round(scale * orig_shape), 1)
     if multichannel:  # don't scale channel dimension
         output_shape[-1] = orig_shape[-1]
 


Test patch:
diff --git a/skimage/transform/tests/test_warps.py b/skimage/transform/tests/test_warps.py
--- a/skimage/transform/tests/test_warps.py
+++ b/skimage/transform/tests/test_warps.py
@@ -475,6 +475,13 @@ def test_downscale_anti_aliasing():
     assert_equal(scaled[:, 3:].sum(), 0)
 
 
+def test_downscale_to_the_limit():
+    img = np.random.rand(3, 4)
+    out = rescale(img, 1e-3)
+
+    assert out.size == 1
+
+
 def test_downscale_local_mean():
     image1 = np.arange(4 * 6).reshape(4, 6)
     out1 = downscale_local_mean(image1, (2, 3))