Answers:
您并不是在说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开始,在图像和numpy数组之间进行转换的“正确”方法很简单
>>> pix = numpy.array(pic)
尽管结果数组的格式与您的格式不同(在这种情况下为3维数组或行/列/ rgb)。
然后,在对阵列进行更改之后,您应该可以执行任一操作pic.putdata(pix)
或使用创建新图像Image.fromarray(pix)
。
Image.fromarray
未在PIL文档中列出(!),所以如果不是这个原因,我将永远找不到。
I
以数组形式打开:
>>> I = numpy.asarray(PIL.Image.open('test.jpg'))
对进行一些处理I
,然后将其转换回图像:
>>> im = PIL.Image.fromarray(numpy.uint8(I))
如果出于某种原因要明确地执行此操作,则此页面上的correlation.zip中有使用getdata()的pil2array()和array2pil()函数。
import Image
第一个吗?您是否已安装PIL?
uint8
转换是否必要?
numpy.asarray(Image.open(filename))
似乎适用于.jpg图像,但不适用于.png。结果显示为array(<PngImagePlugin.PngImageFile image mode=LA size=500x500 at 0x3468198>, dtype=object)
。该对象似乎没有明显命名的方法PngImagePlugin.PngImageFile
来解决此问题。猜猜我应该将其作为一个新问题提出,但这与该主题非常相关。有人知道这是怎么回事吗?
getdata()
返回状物体(序列pillow.readthedocs.io/en/3.4.x/reference/...),但枕头形象实现了__array_interface__
其numpy
可用来访问原始字节无需通过迭代器即可查看图像(请参见github.com/python-pillow/Pillow/blob/…和docs.scipy.org/doc/numpy/reference/arrays.interface.html)。您甚至可以使用numpy.array(PIL.Image.open('test.jpg'))
我在Python 3.5中使用Pillow 4.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数组时,例如在进行转换im2arr = np.rollaxis(im2arr, 2, 0)
或im2arr = np.transpose(im2arr, (2, 0, 1))
转换为CxHxW格式时,我们应注意HxWxC数据格式。
np.flipud
进行修复。尽管我的PIL映像是使用从头开始创建的ImageDraw.Draw
。我认为必须小心其坐标的原点。
您需要通过以下方式将图像转换为numpy数组:
import numpy
import PIL
img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img)
.convert("L")
为.convert("RGB")
我今天使用的示例:
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])
转换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)
pic.size[0]
并pic.size[1]
应被交换(即reshape(pic.size[1], pic.size[0], 3)
),因为size
是width x height
或x * y
,当矩阵排序rows x columns
。