5

It seems the imresize implemented in PIL/scipy.misc only works for uint8 images

>>> import scipy.misc
>>> im = np.random.rand(100,200)
>>> print im.dtype
float64

>>> im2 = scipy.misc.imresize(im, 0.5)
>>> print im2.dtype
uint8

Is there any way around this? I'd like to deal HDR images and therefore needs to deal with float64 or float32 images. Thanks.

Ying Xiong
  • 4,578
  • 8
  • 33
  • 69
  • 1
    Try [scipy.ndimage.interpolation.zoom](http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.ndimage.interpolation.zoom.html) – cgohlke Nov 07 '14 at 06:18
  • Thanks @cgohlke. That works pretty well for me. Would you mind answering the question so that I can accept it and close the question? Thanks! – Ying Xiong Nov 07 '14 at 13:45

3 Answers3

12

Thanks to cgohlke's comment. Below are two alternatives I found that works for float-number images.

  1. Use scipy.ndimage.interpolation.zoom

For single-channel images: im2 = scipy.ndimage.interpolation.zoom(im, 0.5)

For 3-channel images: im2 = scipy.ndimage.interpolation.zoom(im, (0.5, 0.5, 1.0))

  1. Use OpenCV.

im2 = cv2.resize(im, (im.shape[1]/2, im.shape[0]/2))

This works for both single-channel and 3-channel images. Note that one needs to revert the shape order in second parameter.

Ying Xiong
  • 4,578
  • 8
  • 33
  • 69
  • 1
    cv2.resize suggestion is nice since it allows the height and width to be specified exactly in pixels. – Jonathan Feb 09 '16 at 08:44
1

you could also use the mode='F' option in the imresize function

imresize(image, factor, mode='F')
jgroehl
  • 134
  • 6
0

Talking about performance to complement Ying Xiong summary and based on arrays as Numpy.array whose datatype is either int or float, OpenCV is much faster:

import numpy as np
import cv2
from timeit import Timer
from scipy.ndimage import zoom


def speedtest(cmd, N):
    timer = Timer(cmd, globals=globals())
    times = np.array(timer.repeat(repeat=N, number=1))
    print(f'Over {N} attempts, execution took:\n'
          f'{1e3 * times.min():.2f}ms at min\n'
          f'{1e3 * times.max():.2f}ms at max\n'
          f'{1e3 * times.mean():.2f}ms on average')

# My image is 2000x2000, let's try to resize it to 300x300
image_int = np.array(image, dtype= 'uint8')
image_float = np.array(image, dtype= 'float')

N_attempts = 100  # We run the speed test 100 times
speedtest("zoom(image_int, 300/2000)", N_attempts)
# Over 100 attempts, execution took:
# 120.84ms at min
# 135.09ms at max
# 124.50ms on average
speedtest("zoom(image_float, 300/2000)", N_attempts)
# Over 100 attempts, execution took
# 165.34ms at min
# 180.82ms at max
# 169.77ms on average
speedtest("cv2.resize(image_int, (300, 300))", N_attempts)
# Over 100 attempts, execution took
# 0.11ms at min
# 0.26ms at max
# 0.13ms on average
speedtest("cv2.resize(image_float, (300, 300))", N_attempts)
# Over 100 attempts, execution took
# 0.56ms at min
# 0.86ms at max
# 0.62ms on average
C.J
  • 55
  • 7