如何将PIL图像转换为numpy数组?

2024-04-19 15:16:30 发布

您现在位置:Python中文网/ 问答频道 /正文

好吧,我正在把一个PIL图像对象来回转换成一个numpy数组,这样我就可以做一些比PIL的PixelAccess对象允许的更快的逐像素转换。我已经找到了如何将像素信息放置在一个有用的3D numpy数组中,方法是:

pic = Image.open("foo.jpg")
pix = numpy.array(pic.getdata()).reshape(pic.size[0], pic.size[1], 3)

但在完成了所有令人敬畏的转换之后,我似乎不知道如何将其加载回PIL对象中。我知道putdata()方法,但似乎无法使其正常工作。


Tags: 对象方法图像imagenumpy信息sizepil
3条回答

作为数组打开I

>>> I = numpy.asarray(PIL.Image.open('test.jpg'))

做些事情I,然后,将其转换回图像:

>>> im = PIL.Image.fromarray(numpy.uint8(I))

Filter numpy images with FFT, Python

如果出于某种原因要显式执行此操作,correlation.zip中的this page上有使用getdata()的pil2array()和array2pil()函数。

我正在使用Python 3.5中的枕头4.1.1(PIL的继承者)。枕头和纽比之间的转换很简单。

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)

需要注意的一件事是枕头样式im是列主,而numpy样式im2arr是行主。但是,函数Image.fromarray已经考虑到了这一点。也就是上面例子中的arr2im.size == im.sizearr2im.mode == im.mode

在处理转换后的numpy数组时,我们应该注意HxWxC数据格式,例如将im2arr = np.rollaxis(im2arr, 2, 0)im2arr = np.transpose(im2arr, (2, 0, 1))转换为CxHxW格式。

你不是说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开始,"proper" way to convert between images and numpy arrays只是

>>> pix = numpy.array(pic)

尽管结果数组的格式与您的不同(在本例中是三维数组或行/列/rgb)。

然后,在对数组进行更改之后,您应该能够使用pic.putdata(pix)或使用Image.fromarray(pix)创建新图像。

相关问题 更多 >