Python 如何将PIL图像转换为numpy数组?
好的,我正在玩弄如何将一个PIL图像对象来回转换为一个numpy数组,这样我可以做一些比PIL的Python 如何将PIL图像转换为numpy数组?,python,image,numpy,python-imaging-library,numpy-ndarray,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对象。我知道putda
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开始,简单来说
>>> pix = numpy.array(pic)
尽管生成的数组的格式与您的不同(在本例中为三维数组或行/列/rgb)
然后,在对数组进行更改后,您应该能够执行
pic.putdata(pix)
或使用image.fromarray(pix)
创建一个新映像 以数组形式打开I
:
>>> I = numpy.asarray(PIL.Image.open('test.jpg'))
对I
执行一些操作,然后将其转换回图像:
>>> im = PIL.Image.fromarray(numpy.uint8(I))
如果出于某种原因要显式执行此操作,则correlation.zip中有使用getdata()的pil2array()和array2pil()函数。您需要通过以下方式将图像转换为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)
我在Python3.5中使用Pillow4.1.1(PIL的继承者)。枕头和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格式。如果图像以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
然后,我创建了一个helper函数,将数据集更改为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
在这之后,我能够在我的神经网络中使用ByteArray
plt.imshow(imagesList[0])
可以将图像转换为numpy
通过在挤出特征(非规范化)后将图像解析为numpy()函数,将
numpy转换为PIL
图像和PIL转换为numpy
import numpy as np
from PIL import Image
def pilToNumpy(img):
return np.array(img)
def NumpyToPil(img):
return Image.fromarray(img)
首先,它不应该是pic.putdata(数据)吗?而numpy.asarray(pic)生成一个只读数组,所以您需要调用numpy.array(pic),而您没有回答这个问题。。。从您提供的链接来看,它似乎是pic=Image.fromarray(pix)。修正你的答案,我会接受它。谢谢这张…
图片。FROMARY
没有列在PIL文档(!)中,所以如果不是因为这个,我永远也找不到它。该页面将numpy.asarray(pic)
列为转换的“正确”方式,而不是numpy.array(pic)
。按照<代码>数组< /代码>将生成一个副本,而uint8
转换?numpy.asarray(Image.open(filename))
似乎适用于.jpg图像,但不适用于.png。结果显示为数组(,dtype=object)
。似乎没有明显命名的PngImagePlugin.PngImageFile
对象方法来解决这个问题。我想我应该把这个问题作为一个新问题来问,但它与这个主题非常相关。有人知道这里出了什么问题吗?@Rebs:这就是为什么速度要快得多的原因:getdata()
返回一个类似object()的序列,但是枕头图像实现了\uuuuu数组\uu接口
,它可以使用numpy
访问图像的原始字节,而不必通过迭代器(请参阅和)。您甚至可以使用numpy.array(PIL.Image.open('test.jpg'))
@jez在将图像对象转换为numpy之前检查图像对象是否已关闭。同样的情况也发生在我身上,我发现我在某处关闭了图像对象。这种转换方式保留了图像,但会导致颜色丢失。无论如何,为了避免颜色丢失?@moondra如果我理解你的问题,你可以用替换。convert(“L”)
。convert(“RGB”)
“L”生成灰度图像,即pic.size[0]
和pic.size[1]
应该交换(即重塑(pic.size[1],pic.size[0],3)
),因为size
是width x height
或x*y
,而矩阵排序是rows x columns
。这是最干净的示例,包括导入语句(感谢您提供的详细信息)。让我们投票表决这个答案,以提高可见性。我发现,当我将PIL绘制的图像转换为numpy数组时,在数组上使用matplotlib imshow时,它显示为颠倒的,需要使用np.flipud
进行修复。虽然我的PIL图像是使用ImageDraw.Draw
从头开始创建的。我认为人们必须小心他们坐标的来源。
import numpy as np
from PIL import Image
def pilToNumpy(img):
return np.array(img)
def NumpyToPil(img):
return Image.fromarray(img)