¿Cómo convierto una imagen PIL en una matriz NumPy?
¿Cómo convierto un PIL Image
de un lado a otro en una matriz NumPy para poder realizar transformaciones de píxeles más rápidas de las que PixelAccess
permite 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 Image
después de modificar la matriz? pic.putdata()
no está funcionando bien.
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 putdata
espera 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)
.
Abrir I
como una matriz:
>>> I = numpy.asarray(PIL.Image.open('test.jpg'))
Haga algunas cosas para I
luego 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.
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 im
es la columna principal, mientras que el estilo numpy im2arr
es la fila principal. Sin embargo, la función Image.fromarray
ya tiene esto en cuenta. Es decir, arr2im.size == im.size
y arr2im.mode == im.mode
en 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.
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)