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

akd*_*dom 212 python numpy image python-imaging-library numpy-ndarray

好吧,我正在四处寻找将PIL图像对象来回转换为numpy数组,这样我就可以比PIL的PixelAccess对象允许更快的像素转换.我已经想出如何通过以下方式将像素信息放在一个有用的3D numpy数组中:

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

但在完成所有令人敬畏的变换后,我似乎无法弄清楚如何将其加载回PIL对象.我知道这个putdata()方法,但似乎无法让它表现出来.

dF.*_*dF. 249

你不是说究竟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
Run Code Online (Sandbox Code Playgroud)

这是因为putdata需要一系列元组,并且你给它一个numpy数组.这个

>>> data = list(tuple(pixel) for pixel in pix)
>>> pic.putdata(data)
Run Code Online (Sandbox Code Playgroud)

会工作,但它很慢.

从PIL 1.1.6开始,在图像和numpy数组之间进行转换"正确"方法很简单

>>> pix = numpy.array(pic)
Run Code Online (Sandbox Code Playgroud)

虽然生成的数组格式与您的格式不同(在这种情况下为3-d数组或行/列/ rgb).

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

  • 该页面列出了`numpy.asarray(pic)`作为转换的"正确"方式,而非`numpy.array(pic)`.按照[这个答案](http://stackoverflow.com/questions/14415741/numpy-array-vs-asarray),`array`将复制,而`asarray`则不会(但是``asarray`结果将是只读). (12认同)
  • 第二个答案更好。 (3认同)
  • 首先,它不应该是pic.putdata(数据)吗?并且numpy.asarray(pic)生成一个只读数组,所以你需要调用numpy.array(pic),你没有回答这个问题...从你提供的链接看来它似乎是pic = Image.fromarray( PIX).修复你的答案,我会接受它. (2认同)
  • 谢谢你......"Image.fromarray"没有在PIL文档中列出(!)所以如果不是这样的话我就永远找不到它. (2认同)

end*_*ith 168

I以数组形式打开:

>>> I = numpy.asarray(PIL.Image.open('test.jpg'))
Run Code Online (Sandbox Code Playgroud)

做一些东西I,然后,将其转换回图像:

>>> im = PIL.Image.fromarray(numpy.uint8(I))
Run Code Online (Sandbox Code Playgroud)

使用FFT,Python过滤numpy图像

如果由于某种原因想要显式地执行它,则在correlation.zip的此页面上使用getdata()函数有pil2array()和array2pil()函数.

  • 是否需要`uint8`转换? (4认同)
  • `numpy.asarray(Image.open(filename))`似乎适用于.jpg图像,但不适用于.png.结果显示为`array(<PngImagePlugin.PngImageFile image mode = LA size = 500x500 at 0x3468198>,dtype = object)`.似乎没有明确命名的'PngImagePlugin.PngImageFile`对象的方法来解决这个问题.猜猜我应该问这是一个新问题,但它与这个线程非常相关.谁知道这里出了什么问题? (4认同)
  • @Rebs:这就是原因*为什么*这要快得多:`getdata()`返回一个类似对象的序列(http://pillow.readthedocs.io/en/3.4.x/reference/Image.html#PIL. Image.Image.getdata),但是一个枕头图像实现了`__array_interface__`,`numpy`可以用来访问图像的原始字节而不必通过迭代器(参见https://github.com/python-pillow /Pillow/blob/730cf93c32ffb747c018afffe597ef9ae264a20a/PIL/Image.py#L633和https://docs.scipy.org/doc/numpy/reference/arrays.interface.html).你甚至可以使用`numpy.array(PIL.Image.open('test.jpg'))` (3认同)
  • @ArditS.:你先导入Image`吗?你有PIL安装? (2认同)
  • @jez在将Image对象转换为numpy之前检查它是否已关闭.同样的事发生在我身上,我发现我在某处关闭了图像对象. (2认同)

Dan*_*iel 54

我在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)
Run Code Online (Sandbox Code Playgroud)

需要注意的一件事是,Pillow风格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格式.

  • 这是关于最干净的示例,包括import语句(感谢您提供详细信息)。让我们对这个答案进行投票以提高知名度。 (2认同)

Kam*_*mov 19

转换Numpy to PIL图像和PIL to Numpy

import numpy as np
from PIL import Image

def pilToNumpy(img):
    return np.array(img)

def NumpyToPil(img):
    return Image.fromarray(img)
Run Code Online (Sandbox Code Playgroud)


Bil*_*adj 15

您需要以这种方式将图像转换为numpy数组:

import numpy
import PIL

img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img) 
Run Code Online (Sandbox Code Playgroud)

  • @moondra如果我理解你的问题,你可以用`.convert("RGB")替换`.convert("L")`` (6认同)