How to resize image data using numpy?

Question:

I want to resize image data in python, but a simple numpy.resize does not seem to work.

I read the image, and try to resize it using the following script. To check I write the file which results in an unexpected outcome.

from PIL import Image
import numpy as np

# Read image data as black-white image
image = Image.open(input_image).convert("L")
arr = np.asarray(image)

# resize image by factor of 2 (original image has shape (834, 1102) )
image = np.resize(arr, (417, 551))

# same resized image to check if it worked
im = Image.fromarray(image)
im.save("test.jpeg")

The original image:

enter image description here

The rescaled image:

enter image description here

I expect to see the same image (an airplane), but just smaller, with smaller resolution.

What am I doing wrong here?

Asked By: Alex

||

Answers:

from PIL import Image
import numpy as np

# Read image data as black-white image
image = Image.open(input_image).convert("L")
arr = np.asarray(image)

# resize image by factor of 2 (original image has shape (834, 1102) )
image = arr[::2, ::2]

# same resized image to check if it worked
im = Image.fromarray(image)
im.save("test.jpeg")

The terms you can google for are upsampling and downsampling.

Answered By: asds_asds

i think like this
example my code

from PIL import Image
import numpy as np

input_image = r"airplane.jpg"

# Read image data as black-white image
image = Image.open(input_image).convert("L")
arr = np.asarray(image)

# calculate new height and width based on resize factor
resize_factor = 0.5
height, width = arr.shape
new_height = int(height * resize_factor)
new_width = int(width * resize_factor)

# resize image using numpy
resized_image = arr[::2, ::2]

# save resized image
im = Image.fromarray(resized_image)
im.save("resized_image.jpeg")

# show resized image
im.show()

output:
enter image description here

from this:
enter image description here

Answered By: Indra Dwi Aryadi

If you want to scale the image there is no need to use Numpy at all. PIL, which is already installed can do that:

from PIL import Image, ImageOps
im = Image.open('w3IAi.jpg').convert('L')
ImageOps.scale(im, 0.5).save('result.png')
Answered By: Mark Setchell

There are multiple answers and All look valid. I want to add one more and compare them:

The answer

You can use PIL’s resize method:

from PIL import Image
image = Image.open(input_image)
w, h = image.size
resized_image = image.resize((int(w * 0.5), int(h * 0.5)))

Comparison

I expected PIL to be faster.

Here is the script to compare the methods

  1. Method 1: @asds_asds’s numpy method.
  2. Method 2: The PIL’s resize method I provided.
  3. Method 3: @Mark Setchell’s method.

The script:

from PIL import Image, ImageOps
import numpy as np
from time import perf_counter
from matplotlib import pyplot as plt

data = []

for i in range(100, 5000, 200):
    print(i)
    zeros = np.zeros((i, i))
    IMAGE = Image.fromarray(zeros)

    np_start = perf_counter()
    a = np.array(IMAGE)
    _ = a[::2, ::2]
    np_end = perf_counter()

    pil_res_start = perf_counter()
    width, height = IMAGE.size
    IMAGE.resize((int(width * 0.5), int(height * 0.5)))
    pil_res_end = perf_counter()

    pil_scl_start = perf_counter()
    _ = ImageOps.scale(IMAGE, 0.5)
    pil_scl_end = perf_counter()

    data.append([i, np_end - np_start, pil_res_end - pil_res_start, pil_scl_end - pil_scl_start])

data = np.array(data)
plt.plot(data[:, 0], data[:, 1], label="numpy")
plt.plot(data[:, 0], data[:, 2], label="PIL Resize")
plt.plot(data[:, 0], data[:, 3], label="PIL Scale")
plt.legend()
plt.xlabel(r"$sqrt{n_{pix}}$")
plt.ylabel(r"perf_counter (sec)")
plt.title("Numpy vs PIL resize")
plt.show()

Here the results:

Comperastion

TL;DR

Although numpy is faster, the code that PIL provides is cleaner and the gap is not that significant. So PIL might look better…

Answered By: MSH
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.