Search code examples
pythonresizescikit-image

What's the difference between scipy.misc.imresize and skimage.transform.resize?


I am trying to replace some code which uses scipy.misc.imresize with skimage.transform.resize. However, I am struggling to understand some code which performs some math on the results:

import os
import numpy as np
from PIL import Image
from skimage.transform import resize as imresize

# load the image
filename = os.path.join('silhouettes', 'cat.jpg')
image = Image.open(filename)

data = np.asarray(image)
width, height, _ = data.shape
mask = imresize(data, (width, height), order=3).astype('float32')
print(type(mask))

# Perform binarization of mask
mask[mask <= 127] = 0
mask[mask > 128] = 255

# numpy.amax
# Return the maximum of an array or maximum along an axis.
max = np.amax(mask)
print(max)

# RuntimeWarning: invalid value encountered in true_divide
# Attempt to divide an numpy.ndarray by 0
mask /= max

The comments document the error I'm getting: The max value is 0, and I wind up trying to divide by 0. For reference, the original function was:

def load_mask_sil(invert_sil, shape):
    width, height, _ = shape
    mask = imresize(invert_sil, (width, height), interp='bicubic').astype('float32')

    # Perform binarization of mask
    mask[mask <= 127] = 0
    mask[mask > 128] = 255

    max = np.amax(mask)
    mask /= max

    return mask

Solution

  • According to the documentation on skimage.transform.resize, the values in the output are scaled to the interval [0.0 ... 1.0], whereas I assume, that scipy.misc.imresize didn't change the data type or values at all (I don't have such an old version of scipy at hand to verify that).

    So, in the original version, you most likely had values in the range [0.0 ... 255.0], and some values above 128, so that the maximum was 255. In the new version, you only have values in the range [0.0 ... 1.0], thus all pixels will be set to 0, since they're all below 127. (On a side note: Why <= 127 and > 128? What about 128 itself?)

    You can circumvent that issue by enabling the preserve_range flag in your skimage.transform.resize call:

    mask = imresize(data, (width, height), order=3, preserve_range=True).astype('float32')
    

    So, you again get values in the range [0.0 ... 255.0], which should resemble the original behaviour.