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:
The rescaled image:
I expect to see the same image (an airplane), but just smaller, with smaller resolution.
What am I doing wrong here?
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.
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()
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')
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
- Method 1: @asds_asds’s numpy method.
- Method 2: The PIL’s resize method I provided.
- 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:
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…
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:
The rescaled image:
I expect to see the same image (an airplane), but just smaller, with smaller resolution.
What am I doing wrong here?
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.
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()
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')
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
- Method 1: @asds_asds’s numpy method.
- Method 2: The PIL’s resize method I provided.
- 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:
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…