In Python, how can an image stored as a NumPy array be scaled in size?
You can use numpy.kron as suggested in the comment or you can use the following below options
1] Using PILLOW to maintain the Aspect Ratio
If you want to maintain the aspect ratio of the image then you can use
thumbnail()
methodfrom PIL import Imagedef scale_image(input_image_path, output_image_path, width=None, height=None): original_image = Image.open(input_image_path) w, h = original_image.size print('The original image size is {wide} wide x {height} ' 'high'.format(wide=w, height=h)) if width and height: max_size = (width, height) elif width: max_size = (width, h) elif height: max_size = (w, height) else: # No width or height specified raise RuntimeError('Width or height required!') original_image.thumbnail(max_size, Image.ANTIALIAS) original_image.save(output_image_path) scaled_image = Image.open(output_image_path) width, height = scaled_image.size print('The scaled image size is {wide} wide x {height} ' 'high'.format(wide=width, height=height))if __name__ == '__main__': scale_image(input_image_path='caterpillar.jpg', output_image_path='caterpillar_scaled.jpg', width=800)
I used
Image.ANTIALIAS
flag which will apply a high quality down sampling filter which results in a better image
2] Using OpenCV
OpenCV has
cv2.resize()
functionimport cv2image = cv2.imread("image.jpg") # when reading the image the image original size is 150x150print(image.shape)scaled_image = cv2.resize(image, (24, 24)) # when scaling we scale original image to 24x24 print(scaled_image.shape)
Output
(150, 150)(24, 24)
cv2.resize()
function also has interpolation as argument by which you can specify how you want to resize the imageINTERPOLATION METHODS:
- INTER_NEAREST - a nearest-neighbor interpolation
- INTER_LINEAR - a bilinear interpolation (used by default)
- INTER_AREA - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
- INTER_CUBIC - a bicubic interpolation over 4x4 pixel neighborhood
- INTER_LANCZOS4 - a Lanczos interpolation over 8x8 pixel neighborhood
3] Using PILLOW library
Use
Image.resize()
from PIL import Imagesourceimage= Image.open("image.jpg") # original image of size 150x150resized_image = sourceimage.resize((24, 24), resample=NEAREST) # resized image of size 24x24resized_image.show()
4] Using SK-IMAGE library
Use
skimage.transform.resize()
from skimage import ioimage = io.imread("image.jpg")print(image.shape)resized_image = skimage.transform.resize(image, (24, 24))print(resized_image.shape)
Output
(150, 150)(24, 24)
5] Use SciPy
Use
scipy.misc.imresize()
functionimport numpy as npimport scipy.miscimage = scipy.misc.imread("image.jpg")print(image.shape)resized_image = scipy.misc.imresize(x, (24, 24))resized_imageprint(resized_image.shape)
Output
(150, 150)(24, 24)
In scikit-image
, we have transform
from skimage import transform as tfimport matplotlib.pyplot as pltimport numpy as npdata = np.random.random((1, 15, 3))*255data = data.astype(np.uint8)new_data = tf.resize(data, (600, 300, 3), order=0) # order=0, Nearest-neighbor interpolationf, (ax1, ax2, ax3) = plt.subplots(1,3, figsize=(10, 10))ax1.imshow(data)ax2.imshow(new_data)ax3.imshow(tf.resize(data, (600, 300, 3), order=1))
Here's a snippet of code that resizes an image stored in a numpy array using PIL. In this example, img
is a two-dimensional numpy array.
from PIL import Imageimport numpy as npnr,nc = img.shapeshrinkFactor = .5img_pil = Image.fromarray(img)img_pil = img_pil.resize((round(nc*shrinkFactor),round(nr*shrinkFactor)))img_resized = np.array(img_pil)