Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a PIL Image into a numpy array?

Alright, I'm toying around with converting a PIL image object back and forth to a numpy array so I can do some faster pixel by pixel transformations than PIL's PixelAccess object would allow. I've figured out how to place the pixel information in a useful 3D numpy array by way of:

pic = Image.open("foo.jpg") pix = numpy.array(pic.getdata()).reshape(pic.size[0], pic.size[1], 3) 

But I can't seem to figure out how to load it back into the PIL object after I've done all my awesome transforms. I'm aware of the putdata() method, but can't quite seem to get it to behave.

like image 464
akdom Avatar asked Dec 21 '08 18:12

akdom


People also ask

Can an image could be converted into a NumPy array?

Using OpenCV Library imread() function is used to load the image and It also reads the given image (PIL image) in the NumPy array format. Then we need to convert the image color from BGR to RGB. imwrite() is used to save the image in the file.


2 Answers

You're not saying how exactly putdata() is not behaving. I'm assuming you're doing

>>> 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 

This is because putdata expects a sequence of tuples and you're giving it a numpy array. This

>>> data = list(tuple(pixel) for pixel in pix) >>> pic.putdata(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 Image.fromarray(pix).

like image 137
dF. Avatar answered Oct 19 '22 23:10

dF.


Open I as an array:

>>> I = numpy.asarray(PIL.Image.open('test.jpg')) 

Do some stuff to I, then, convert it back to an image:

>>> im = PIL.Image.fromarray(numpy.uint8(I)) 

Source: Filter numpy images with FFT, Python

If you want to do it explicitly for some reason, there are pil2array() and array2pil() functions using getdata() on this page in correlation.zip.

like image 43
endolith Avatar answered Oct 19 '22 23:10

endolith