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

时间:2008-12-21 18:21:32

标签: python image numpy 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)

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

8 个答案:

答案 0 :(得分:208)

你并没有说明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)

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

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

答案 1 :(得分:147)

打开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()函数。

答案 2 :(得分:45)

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

需要注意的一件事是,枕头式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格式。

答案 3 :(得分:11)

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

import numpy
import PIL

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

答案 4 :(得分:5)

转换 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)

答案 5 :(得分:3)

我今天使用的例子:

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)

答案 6 :(得分:0)

如果图像以Blob格式存储(即存储在数据库中),则可以使用Billal Begueradj解释的相同技术,将图像从Blob转换为字节数组。

就我而言,我需要将图像存储在数据库表的blob列中:

def select_all_X_values(conn):
    cur = conn.cursor()
    cur.execute("SELECT ImageData from PiecesTable")    
    rows = cur.fetchall()    
    return rows

然后我创建了一个辅助函数,将我的数据集更改为np.array:

X_dataset = select_all_X_values(conn)
imagesList = convertToByteIO(np.array(X_dataset))

def convertToByteIO(imagesArray):
    """
    # Converts an array of images into an array of Bytes
    """
    imagesList = []

    for i in range(len(imagesArray)):  
        img = Image.open(BytesIO(imagesArray[i])).convert("RGB")
        imagesList.insert(i, np.array(img))

    return imagesList

此后,我便可以在神经网络中使用byteArrays。

plt.imshow(imagesList[0])

答案 7 :(得分:0)

def imshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()

您可以将图像转换为numpy 压缩特征后将图像解析为numpy()函数(非规范化)