Broadcasting error when vectorizing misc.imresize(

2019-05-31 14:40发布

I have a numpy array A composed of multiple same sized images [N_images,width,height,3].

I want to apply misc.imresize() to each and everyone of them the fastest way possible.

So I defined:

def myfunc(x):
  return misc.imresize(x,(wanted_width,wanted_height))

and then I did:

vfunc=np.vectorize(my_func)

but when I try:

test=vfunc(A)

I get a not-suitable-array-shape-for-converting-into-images error. I thought it was because I did not specify the axis on which the op should be vectorized, which caused it to not broadcast the array ops the way to wanted so I tried another thing to narrow down the error:

test=np.apply_along_axis(my_func,0,A)

and got the same error. Even if I force a np.squeeze() into my_func. That really surprised me.

EDIT: I also tried with map same error. It might stem from the fact that you can only use vectorize with scalar function as pointed out by @jotasi.

It must be pretty silly but I do not know what is going on. Could somebody enlighten me ? Is there a way to fix it ?

1条回答
Anthone
2楼-- · 2019-05-31 15:30

There is an alternative vectorized approach using scipy's zoom. However, it is not necessarily faster for small amount of images (e.g. for N=100 a loop might be faster).

>>> from skimage import color, util, data
>>> img = util.img_as_float(color.gray2rgb(data.camera())) # Sample RGB image

I did just replicate a gray-scale image over the RGB channels, so it will still look gray-scale, but it is RGB in practice.

Create 100 RGB images by replicating above RGB image and its horizontal flip (to ensure interpolation is working properly).

>>> data = np.empty((100,) + img.shape, img.dtype)
>>> data[0::2] = img
>>> data[1::2] = img[:,::-1]
>>> plt.imshow(data[50])

enter image description here

Find zooming factors:

>>> from scipy.ndimage import zoom
>>> new_size = (200, 200)
>>> fy, fx = np.asarray(new_size, np.float32) / data.shape[1:3]

Resize image, factor of 1 means no interpolation over that axis:

>>> resized = zoom(data, (1, fy, fx, 1), order=0) # order=0 for quicker
>>> plt.imshow(resized[50]) # resized.shape = (100, 200, 200, 3)

enter image description here

Again, be aware that although it is a vectorized version, it uses NN interpolation in order to be quick, a standard loop + arbitrary interpolation might be way faster. Take this as a proof of concept and have a look if it works for you.

查看更多
登录 后发表回答