How to convert a PIL Image into a numpy array?
You're not saying how exactly
putdata() is not behaving. I'm assuming you're doing
"...blablabla.../PIL/Image.py", line 1185, in putdata self.im.putdata(data, scale, offset)SystemError: new style getargs format but argument is not a tuplepic.putdata(a)Traceback (most recent call last): File
This is because
putdata expects a sequence of tuples and you're giving it a numpy array. This
list(tuple(pixel) for pixel in pix) pic.putdata(data)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
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).
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
I as an array:
open('test.jpg'))I = numpy.asarray(PIL.Image.
Do some stuff to
I, then, convert it back to an image:
im = PIL.Image.fromarray(numpy.uint8(I))
If you want to do it explicitly for some reason, there are pil2array() and array2pil() functions using getdata() on this page in correlation.zip.
I am using Pillow 4.1.1 (the successor of PIL) in Python 3.5. The conversion between Pillow and numpy is straightforward.
from PIL import Imageimport numpy as npim = Image.open('1.jpg')im2arr = np.array(im) # im2arr.shape: height x width x channelarr2im = 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.
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.