好吧,我正在四处寻找将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()
方法,但似乎不能让它表现得好。
你不是说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)
创建新图像。
打开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中使用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.size
和arr2im.mode == im.mode
在上面的例子中。
在处理转换后的numpy数组时,我们应该处理HxWxC数据格式,例如:将im2arr = np.rollaxis(im2arr, 2, 0)
或im2arr = np.transpose(im2arr, (2, 0, 1))
转换为CxHxW格式。
您需要以这种方式将图像转换为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)
如果您的图像以Blob格式存储(即在数据库中),您可以使用Billal Begueradj解释的相同技术将图像从Blob转换为字节数组。
就我而言,我需要存储在db表中的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])
def imshow(img):
img = img / 2 + 0.5 # unnormalize
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))
plt.show()
通过在压缩特征之后将图像解析为numpy()函数,可以将图像转换为numpy(非标准化)