我如何将PIL图像来回转换为NumPy数组,以便我可以比PIL的PixelAccess更快地进行逐像素转换?我可以通过以下方式将其转换为NumPy数组:
pic = Image.open("foo.jpg")
pix = numpy.array(pic.getdata()).reshape(pic.size[0], pic.size[1], 3)
但我如何加载它回到PIL图像后,我已经修改了数组?picture .putdata()工作不正常。
我如何将PIL图像来回转换为NumPy数组,以便我可以比PIL的PixelAccess更快地进行逐像素转换?我可以通过以下方式将其转换为NumPy数组:
pic = Image.open("foo.jpg")
pix = numpy.array(pic.getdata()).reshape(pic.size[0], pic.size[1], 3)
但我如何加载它回到PIL图像后,我已经修改了数组?picture .putdata()工作不正常。
当前回答
您没有说putdata()的行为是如何不正确的。我猜你在做
>>> pic.putdata(a)
Traceback (most recent call last):
File "...blablabla.../PIL/Image.py", line 1185, in putdata
self.im.putdata(data, scale, offset)
SystemError: new style getargs format but argument is not a tuple
这是因为putdata需要一个元组序列,而您给了它一个numpy数组。这
>>> data = list(tuple(pixel) for pixel in pix)
>>> pic.putdata(data)
会起作用,但很慢。
从PIL 1.1.6开始,在图像和numpy数组之间进行转换的“正确”方法很简单
>>> pix = numpy.array(pic)
尽管结果数组的格式与您的不同(在这种情况下是3d数组或rows/columns/rgb)。
然后,在对数组进行更改之后,您应该能够执行pic.putdata(pix)或使用image .fromarray(pix)创建新图像。
其他回答
您没有说putdata()的行为是如何不正确的。我猜你在做
>>> pic.putdata(a)
Traceback (most recent call last):
File "...blablabla.../PIL/Image.py", line 1185, in putdata
self.im.putdata(data, scale, offset)
SystemError: new style getargs format but argument is not a tuple
这是因为putdata需要一个元组序列,而您给了它一个numpy数组。这
>>> data = list(tuple(pixel) for pixel in pix)
>>> pic.putdata(data)
会起作用,但很慢。
从PIL 1.1.6开始,在图像和numpy数组之间进行转换的“正确”方法很简单
>>> pix = numpy.array(pic)
尽管结果数组的格式与您的不同(在这种情况下是3d数组或rows/columns/rgb)。
然后,在对数组进行更改之后,您应该能够执行pic.putdata(pix)或使用image .fromarray(pix)创建新图像。
将I作为数组打开:
>>> I = numpy.asarray(PIL.Image.open('test.jpg'))
对I做一些操作,然后将它转换回图像:
>>> im = PIL.Image.fromarray(numpy.uint8(I))
来源:使用FFT过滤numpy图像,Python
如果您出于某种原因想显式地执行此操作,在related .zip中的此页上有pil2array()和array2pil()函数使用getdata()。
你需要将你的图像转换为numpy数组:
import numpy
import PIL
img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img)
我今天用的例子是:
import PIL
import numpy
from PIL import Image
def resize_image(numpy_array_image, new_height):
# convert nympy array image to PIL.Image
image = Image.fromarray(numpy.uint8(numpy_array_image))
old_width = float(image.size[0])
old_height = float(image.size[1])
ratio = float( new_height / old_height)
new_width = int(old_width * ratio)
image = image.resize((new_width, new_height), PIL.Image.ANTIALIAS)
# convert PIL.Image into nympy array back again
return array(image)
我使用的是Python 3.5中的Pillow 4.1.1 (PIL的继承者)。Pillow和numpy之间的转换很简单。
from PIL import Image
import numpy as np
im = Image.open('1.jpg')
im2arr = np.array(im) # im2arr.shape: height x width x channel
arr2im = Image.fromarray(im2arr)
需要注意的一点是,pillow风格的im是列为主的,而numpy风格的im2arr是行为主的。然而,函数Image.fromarray已经考虑到了这一点。也就是arr2im。Size == im。尺寸和长度。Mode == im。模式在上面的例子。
在处理转换后的numpy数组时,我们应该注意HxWxC数据格式,例如执行转换im2arr = np。rol速(im2arr, 2,0)或im2arr = np。将(im2arr,(2,0,1))转置为CxHxW格式。