¿Cómo convierto una imagen PIL en una matriz NumPy?

Resuelto akdom asked hace 15 años • 9 respuestas

¿Cómo convierto un PIL Imagede un lado a otro en una matriz NumPy para poder realizar transformaciones de píxeles más rápidas de las que PixelAccesspermite PIL? Puedo convertirlo en una matriz NumPy mediante:

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

Pero, ¿cómo lo vuelvo a cargar en PIL Imagedespués de modificar la matriz? pic.putdata()no está funcionando bien.

akdom avatar Dec 22 '08 01:12 akdom
Aceptado

No estás diciendo exactamente cómo putdata()no comportarse. Supongo que lo estás haciendo

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

Esto se debe a que putdataespera una secuencia de tuplas y le estás dando una matriz numerosa. Este

>>> data = list(tuple(pixel) for pixel in pix)
>>> pic.putdata(data)

Funcionará pero es muy lento.

A partir de PIL 1.1.6, la forma "adecuada" de convertir entre imágenes y matrices numerosas es simplemente

>>> pix = numpy.array(pic)

aunque la matriz resultante tiene un formato diferente al suyo (matriz tridimensional o filas/columnas/rgb en este caso).

Luego, después de realizar los cambios en la matriz, debería poder hacerlo pic.putdata(pix)o crear una nueva imagen con Image.fromarray(pix).

dF. avatar Dec 21 '2008 20:12 dF.

Abrir Icomo una matriz:

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

Haga algunas cosas para Iluego convertirlo nuevamente en una imagen:

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

Fuente: Filtrar numerosas imágenes con FFT, Python

Si desea hacerlo explícitamente por algún motivo, hay funciones pil2array() y array2pil() que usan getdata() en esta página en correlación.zip.

endolith avatar Jul 08 '2009 02:07 endolith

Estoy usando Pillow 4.1.1 (el sucesor de PIL) en Python 3.5. La conversión entre Pillow y numpy es sencilla.

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)

Una cosa que hay que tener en cuenta es que el estilo Pillow imes la columna principal, mientras que el estilo numpy im2arres la fila principal. Sin embargo, la función Image.fromarrayya tiene esto en cuenta. Es decir, arr2im.size == im.sizey arr2im.mode == im.modeen el ejemplo anterior.

Deberíamos cuidar el formato de datos HxWxC al procesar los numpy arrays transformados, por ejemplo, hacer la transformación im2arr = np.rollaxis(im2arr, 2, 0)o im2arr = np.transpose(im2arr, (2, 0, 1))al formato CxHxW.

Daniel avatar Jun 17 '2017 16:06 Daniel

Necesita convertir su imagen en una matriz numerosa de esta manera:

import numpy
import PIL

img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img) 
Billal Begueradj avatar Jun 07 '2016 09:06 Billal Begueradj