Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resize a batch of images in numpy

I have close to 10000 greyscale images in a numpy array (10000 x 480 x 752) and would like to resize them with the imresize function from scipy.misc. It works with a for loop build around all the images, but it takes 15 minutes.

images_resized = np.zeros([0, newHeight, newWidth], dtype=np.uint8)
for image in range(images.shape[0]):
    temp = imresize(images[image], [newHeight, newWidth], 'bilinear')
    images_resized = np.append(images_resized, np.expand_dims(temp, axis=0), axis=0)

Is there any way to do this faster with an apply like function? I looked into apply_along_axis

def resize_image(image):
    return imresize(image, [newHeight, newWidth], 'bilinear')
np.apply_along_axis(lambda x: resize_image(x), 0, images)

but this gives an

'arr' does not have a suitable array shape for any mode

error.

like image 264
Peter Lenaers Avatar asked Mar 02 '16 09:03

Peter Lenaers


People also ask

How do I resize multiple images at once in Python?

You can resize multiple images in Python with the awesome PIL library and a small help of the os (operating system) library. By using os. listdir() function you can read all the file names in a directory. After that, all you have to do is to create a for loop to open, resize and save each image in the directory.

What is the difference between reshape () and resize ()?

reshape() and numpy. resize() methods are used to change the size of a NumPy array. The difference between them is that the reshape() does not changes the original array but only returns the changed array, whereas the resize() method returns nothing and directly changes the original array.

How do I change the size of an array in NumPy?

The shape of the array can also be changed using the resize() method. If the specified dimension is larger than the actual array, The extra spaces in the new array will be filled with repeated copies of the original array.


1 Answers

the time is long probably because resize is long :

In [22]: %timeit for i in range(10000) : pass
1000 loops, best of 3: 1.06 ms per loop

so the time is spend by the resize function: Vectorisation will not improve performance here.

Estimate time for one image is 15*60/10000= 90ms. resize use splines. It is good for quality, but time consuming. if the goal is to reduce size, resampling can give acceptable results and is faster:

In [24]: a=np.rand(752,480)

In [25]: %timeit b=a[::2,::2].copy()
1000 loops, best of 3: 369 µs per loop #

In [27]: b.shape
Out[27]: (376, 240) 

It's about 300x faster. This way, you can achieve the job in a few seconds.

like image 170
B. M. Avatar answered Sep 27 '22 21:09

B. M.