How to resize image data

I have image dataset : (55000,32,32,3)
I want to make this image to (55000,28,28,3)

This data is numpy.ndarray type.
I tried data.resize(55000,28,28,3) but there is error.

ValueError: resize only works on single-segment arrays

How can I resize this image?

What kind of resize do you want to do? Do you want to actually rescale the images (downsampling), or do you want to select the center 28x28 pixels, dis arding the rest (cropping)?

Is this a preprocessing operation (before the data goes into your model), or do you want to do this as part of your model?

Also, are you using a dataloader to read the images, or are you getting the data array from somewhere else?

I just want to re-scaling not cropping.
MNIST size is 28x28, and SVHN is 32x32.
so I want to make this images to have same size.
and then I input those images to my network.

In that case, the standard approach is to transform the images during data loading. Note the transforms variable in this example: you can add a Resize operation to that pipeline (before the ToTensor) to scale the images.

If you’re not using a dataloader, it’s a bit trickier. I think the best option is to transform your data to numpy, use scikit-image to resize the images and then transform it back to pytorch.

Cropping would actually be easier. For that you could just do:
data = data[:, :, 2:31, 2:31]

Note that pytorch image arrays are dimensioned as (batch, channels, height, width).

2 Likes

@pbloem
I want to calculate pixel-mean to normalization.
To do this, Should I use scikit-image ?

Original size : [55000, 32, 32, 3]
I want to make this to [55000,28, 28, 3]

Sorry, I don’t understand what you mean by “pixel-mean to normalization.”

If you want downsample the images, and you’re not using torchvision to load the data, then yes, scikit-image is a good option.

Original images have [55000, 32, 32, 3] shape as numpy.ndarray.

I applied rescale(svhn_train, 0.875).shape
and It becomes [48125, 28, 28, 3].
What`s wrong in my rescaling?

Two things have gone wrong. First, scikit assumes that the first dimensions are to be rescaled. Second, it assumes that the data is a single 3D image (because it has 4 dimensions), instead of many 2D images, so it rescales the first 3 dimensions.

I also linked to the wrong function… resize is easier to use.

Try something like this:

data = np.transpose(data, (1, 2, 3, 0)) # put height and width in front
data = skimage.transform.resize(data, (28, 28)) 
data = np.transpose(data, (3, 0, 1, 2) ) # move back 
svhn_train = svhn_train.transpose((2, 3, 1, 0)) # [32, 32, 3, 55000]

svhn_train = resize(svhn_train, (28, 28))
-> ValueError: len(output_shape) cannot be smaller than the image dimensions


Sorry, looks like resize() doesn’t handle extra dimensions the way I thought. Bit of a hack, but you can fold the batch dimension into the channel dimension:

data = data.transpose((1, 2, 3, 0)) 
data = resize(data.reshape(32, 32, -1), (28, 28)) 
data = data.reshape(28, 28, 3, -1)
data = data.transpose((3, 0, 1, 2))

This doesn’t give me any errors when I try it with a random array (but you may want to plot of few images to make sure nothing gets messed up).

I check that size is changed.
I plot the images but image sizes are equal (resolutions are different.)
I use this code.

def imshow_grid

(images, shape=[2, 8]):
    """Plot images in a grid of a given shape."""
    fig = plt.figure(1)
    grid = ImageGrid(fig, 111, nrows_ncols=shape, axes_pad=0.05)

    size = shape[0] * shape[1]
    for i in range(size):
        grid[i].axis('off')
        grid[i].imshow(images[i])  # The AxesGrid object work as a list of axes.

    plt.show()

32x32
32x32 !
28x28
28x28

My data.size is (321,321,3),and I want to resize to (48,48,3).
I meet the same problem that the size change to (48,48,3),but the image is very burry.
Can you give me a solution? Thank you!

Try using transforms. It has a resize option too