willbecoding
willbecoding

Reputation: 3

Change shape, upscale, image array in Neural Net

I have an array of image pixel values that I would like to upscale for input into my neural network. It is an array of shape (28000, 48, 48, 1). These are normalized image pixel values and would like to upscale these to a higher resolution for input into my CNN. The arrays look like this...

array([[[[-0.6098866 ],
         [-0.4592209 ],
         [-0.40325198],
         ...,
         [-0.7694696 ],
         [-0.90518403],
         [-0.95160526]],

        [[-0.66049284],
         [-0.68162924],
         [-0.694159  ],

Both my X_train and y_train image arrays have shape of (28000,48,48,1). I would like to upscale or resize these 28000 image arrays to size 75x75. Please help. Should I convert arrays back to non-normalized arrays or images and then maybe use cv2 to upscale? How would I do this?

Upvotes: 0

Views: 1082

Answers (1)

Jake Levi
Jake Levi

Reputation: 1730

One easy way to resize images is using the Python module PIL (Python Image Library), which you can install with pip install pillow. Example below to demonstrate resizing a single image:

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

# Open image
panda_pil = Image.open("panda.jpg")
print(np.array(panda_pil).shape)
# (613, 696, 3)

panda_pil_resized = panda_pil.resize((75, 75))
print(np.array(panda_pil_resized).shape)
# (75, 75, 3)

plt.imshow(np.array(panda_pil_resized))
plt.show()

You can download the panda image as follows:

import urllib.request

panda_fname = "panda.jpg"
panda_url = "https://upload.wikimedia.org/wikipedia/commons/f/fe/Giant_Panda_in_Beijing_Zoo_1.JPG"
urllib.request.urlretrieve(panda_url, panda_fname)

To resize all 28000 images, one approach would be to do this as a preprocessing step in a for-loop, and save the images to a numpy array.

Edit: You can loop through your original 28000x2304 image array and upscale each image individually in a for-loop. To get the PIL.Image object from a np.ndarray object, you can use Pil.Image.from_array, as shown below (I have just generated a random array of Gaussian noise but it should work the same with your images):

import numpy as np
from PIL import Image
from time import perf_counter

old_width, old_height = 48, 48
new_width, new_height = 75, 75
num_images = 28000

old_image_array = np.random.normal(size=[num_images, old_width*old_height])
new_image_array = np.empty(shape=[num_images, new_width*new_height])

print("Starting conversion...")
t0 = perf_counter()

# Loop over each image individually
for i in range(num_images):
    # Get the ith image and reshape
    old_image = old_image_array[i].reshape(old_width, old_height)
    # Convert to PIL.Image
    old_image_pil = Image.fromarray(old_image)
    # Upscale resolution
    new_image_pil = old_image_pil.resize((new_width, new_height))
    # Convert to numpy array
    new_image = np.array(new_image_pil)
    # Reshape and store in new image array
    new_image_array[i] = new_image.reshape(new_width*new_height)

t1 = perf_counter()
print("Time taken = {:.3f} s".format(t1 - t0))
print(old_image_array.shape, new_image_array.shape)

Console output:

Starting conversion...
Time taken = 2.771 s
(28000, 2304) (28000, 5625)

There may well be a more efficient way of doing this, but this method is simple, and uses tools which are useful to know about if you don't know about them already (PIL is a good module for manipulating images, see this blog post if you want to learn more about PIL).

Upvotes: 2

Related Questions