我想在 python 中调整图像数据的大小,但简单的 numpy.resize
似乎不起作用。
我读取了图像,并尝试使用以下脚本调整其大小。为了进行检查,我编写了导致意外结果的文件。
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")
原图:
重新缩放后的图像:
我希望看到相同的图像(一架飞机),但尺寸更小,分辨率更小。
我在这里做错了什么?
最佳答案
有多个答案,而且所有答案看起来都有效。我想再添加一个并进行比较:
答案
您可以使用PIL的调整大小方法:
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)))
比较
我预计 PIL 会更快。
这是比较方法的脚本
- 方法 1:@asds_asds 的 numpy 方法。
- 方法2:我提供的PIL的resize方法。
- 方法 3:@Mark Setchell 的方法。
脚本:
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()
结果如下:
TL;DR
虽然 numpy 更快,但 PIL 提供的代码更干净,差距也不是那么大。所以 PIL 可能看起来更好......
关于python - 如何使用numpy调整图像数据的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75963822/