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

时间:2022-11-29 21:27:08

Alright, I'm toying around with converting a PIL image object back and forth to a numpy array so I can do some faster pixel by pixel transformations than PIL's PixelAccess object would allow. I've figured out how to place the pixel information in a useful 3D numpy array by way of:

好了,我要把一个PIL图像对象来回转换成一个numpy数组,这样我就可以通过像素变换比PIL的PixelAccess对象允许的更快一些。我已经知道如何将像素信息放在一个有用的3D numpy数组中,方法如下:

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

But I can't seem to figure out how to load it back into the PIL object after I've done all my awesome transforms. I'm aware of the putdata() method, but can't quite seem to get it to behave.

但是,在我完成了所有可怕的转换之后,我似乎不知道如何将它加载回PIL对象。我知道putdata()方法,但似乎不能让它正常工作。

5 个解决方案

#1


151  

You're not saying how exactly putdata() is not behaving. I'm assuming you're doing

您没有说确切的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

This is because putdata expects a sequence of tuples and you're giving it a numpy array. This

这是因为putdata需要一个元组序列,而你给它一个numpy数组。这

>>> data = list(tuple(pixel) for pixel in pix)
>>> pic.putdata(data)

will work but it is very slow.

会起作用,但很慢。

As of PIL 1.1.6, the "proper" way to convert between images and numpy arrays is simply

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

>>> pix = numpy.array(pic)

although the resulting array is in a different format than yours (3-d array or rows/columns/rgb in this case).

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

Then, after you make your changes to the array, you should be able to do either pic.putdata(pix) or create a new image with Image.fromarray(pix).

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

#2


112  

Open I as an array:

将I作为数组打开:

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

Do some stuff to I, then, convert it back to an image:

做一些事情给我,然后,把它转换回一个图像:

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

Filter numpy images with FFT, Python

使用FFT、Python过滤numpy图像

If you want to do it explicitly for some reason, there are pil2array() and array2pil() functions using getdata() on this page in correlation.zip.

如果您出于某种原因想要显式地执行它,那么在correlation.zip中,这个页面上有使用getdata()的pil2array()和array2pil()函数。

#3


19  

I am using Pillow 4.1.1 (the successor of PIL) in Python 3.5. The conversion between Pillow and numpy is straightforward.

在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)

One thing that needs noticing is that Pillow-style im is column-major while numpy-style im2arr is row-major. However, the function Image.fromarray already takes this into consideration. That is, arr2im.size == im.size and arr2im.mode == im.mode in the above example.

需要注意的一点是枕头样式的im是列大调的,而numpy样式的im2arr是行大调的。然而,函数Image.fromarray已经考虑到了这一点。也就是说,arr2im。= =我大小。大小和arr2im。模式= =我。模式在上面的例子。

We should take care of the HxWxC data format when processing the transformed numpy arrays, e.g. do the transform im2arr = np.rollaxis(im2arr, 2, 0) or im2arr = np.transpose(im2arr, (2, 0, 1)) into CxHxW format.

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

#4


6  

You need to convert your image to a numpy array this way:

您需要将图像转换为numpy数组:

import numpy
import PIL

img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img) 

#5


2  

The example, I have used today:

我今天举了一个例子:

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)

#1


151  

You're not saying how exactly putdata() is not behaving. I'm assuming you're doing

您没有说确切的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

This is because putdata expects a sequence of tuples and you're giving it a numpy array. This

这是因为putdata需要一个元组序列,而你给它一个numpy数组。这

>>> data = list(tuple(pixel) for pixel in pix)
>>> pic.putdata(data)

will work but it is very slow.

会起作用,但很慢。

As of PIL 1.1.6, the "proper" way to convert between images and numpy arrays is simply

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

>>> pix = numpy.array(pic)

although the resulting array is in a different format than yours (3-d array or rows/columns/rgb in this case).

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

Then, after you make your changes to the array, you should be able to do either pic.putdata(pix) or create a new image with Image.fromarray(pix).

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

#2


112  

Open I as an array:

将I作为数组打开:

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

Do some stuff to I, then, convert it back to an image:

做一些事情给我,然后,把它转换回一个图像:

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

Filter numpy images with FFT, Python

使用FFT、Python过滤numpy图像

If you want to do it explicitly for some reason, there are pil2array() and array2pil() functions using getdata() on this page in correlation.zip.

如果您出于某种原因想要显式地执行它,那么在correlation.zip中,这个页面上有使用getdata()的pil2array()和array2pil()函数。

#3


19  

I am using Pillow 4.1.1 (the successor of PIL) in Python 3.5. The conversion between Pillow and numpy is straightforward.

在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)

One thing that needs noticing is that Pillow-style im is column-major while numpy-style im2arr is row-major. However, the function Image.fromarray already takes this into consideration. That is, arr2im.size == im.size and arr2im.mode == im.mode in the above example.

需要注意的一点是枕头样式的im是列大调的,而numpy样式的im2arr是行大调的。然而,函数Image.fromarray已经考虑到了这一点。也就是说,arr2im。= =我大小。大小和arr2im。模式= =我。模式在上面的例子。

We should take care of the HxWxC data format when processing the transformed numpy arrays, e.g. do the transform im2arr = np.rollaxis(im2arr, 2, 0) or im2arr = np.transpose(im2arr, (2, 0, 1)) into CxHxW format.

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

#4


6  

You need to convert your image to a numpy array this way:

您需要将图像转换为numpy数组:

import numpy
import PIL

img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img) 

#5


2  

The example, I have used today:

我今天举了一个例子:

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)