Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Python, how can an image stored as a NumPy array be scaled in size?

I have created a NumPy array in the following way:

data = numpy.zeros((1, 15, 3), dtype = numpy.uint8)

I then filled this array with RGB pixel values, resulting in a little colour image that can be saved using a procedure such as the following:

image = Image.fromarray(data)
image.save("image.png")

How could I scale up the size of the NumPy array (without interpolation) for the purposes of creating an image that is, say, 600 x 300 pixels?

like image 464
d3pd Avatar asked Sep 01 '15 16:09

d3pd


People also ask

How do I resize a NumPy array in Python?

With the help of Numpy numpy. resize(), we can resize the size of an array. Array can be of any shape but to resize it we just need the size i.e (2, 2), (2, 3) and many more. During resizing numpy append zeros if values at a particular place is missing.

Can an image could be converted into a NumPy array?

Using OpenCV Library imread() function is used to load the image and It also reads the given image (PIL image) in the NumPy array format. Then we need to convert the image color from BGR to RGB. imwrite() is used to save the image in the file.

Can NumPy array store images?

fromarray() Function to Save a NumPy Array as an Image. The fromarray() function is used to create an image memory from an object which exports the array. We can then save this image memory to our desired location by providing the required path and the file name.


2 Answers

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() method

    from PIL import Image
    
    def 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() function

    import cv2
    image = cv2.imread("image.jpg")   # when reading the image the image original size is 150x150
    print(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 image
  • INTERPOLATION 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 Image
    sourceimage= Image.open("image.jpg")   # original image of size 150x150
    resized_image = sourceimage.resize((24, 24), resample=NEAREST)  # resized image of size 24x24
    resized_image.show()
    

4] Using SK-IMAGE library

  • Use skimage.transform.resize()

    from skimage import io
    image = 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() function

    import numpy as np
    import scipy.misc
    
    image = scipy.misc.imread("image.jpg")
    print(image.shape)
    resized_image = scipy.misc.imresize(x, (24, 24))
    resized_image
    print(resized_image.shape)
    
  • Output

    (150, 150)
    (24, 24)
    
like image 52
Jai Avatar answered Oct 20 '22 01:10

Jai


In scikit-image, we have transform

from skimage import transform as tf
import matplotlib.pyplot as plt
import numpy as np
data = np.random.random((1, 15, 3))*255
data = data.astype(np.uint8)
new_data = tf.resize(data, (600, 300, 3), order=0) # order=0, Nearest-neighbor interpolation
f, (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))

enter image description here

like image 34
CT Zhu Avatar answered Oct 20 '22 00:10

CT Zhu