python - recorrer - ¿Cómo convertir una imagen PIL en una matriz numpy?
python leer imagenes (5)
De acuerdo, estoy jugando con la conversión de un objeto de imagen PIL de ida y vuelta a una matriz numpy para poder hacer algunas transformaciones más rápidas de píxel por píxel que lo que permitiría el objeto PixelAccess
de PIL. He descubierto cómo colocar la información de píxeles en una útil matriz 3D Numpy a través de:
pic = Image.open("foo.jpg")
pix = numpy.array(pic.getdata()).reshape(pic.size[0], pic.size[1], 3)
Pero parece que no puedo encontrar la manera de volver a cargarlo en el objeto PIL después de haber hecho todas mis increíbles transformaciones. putdata()
método putdata()
, pero no puedo hacer que se comporte.
Abra I
como una matriz:
>>> I = numpy.asarray(PIL.Image.open(''test.jpg''))
Haz algunas cosas a I
, luego, conviértalo de nuevo a una imagen:
>>> im = PIL.Image.fromarray(numpy.uint8(I))
Filtrar imágenes numpy con FFT, Python
Si desea hacerlo explícitamente por algún motivo, existen las funciones pil2array () y array2pil () que usan getdata () en esta página en correlation.zip.
El ejemplo, lo he usado hoy:
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)
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 se debe tener en cuenta es que Pillow-style im
es column-major mientras que im2arr im- im2arr
es fila-major. 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 ocuparnos del formato de datos HxWxC al procesar las matrices numpy transformadas, por ejemplo, hacer la transformación im2arr = np.rollaxis(im2arr, 2, 0)
o im2arr = np.transpose(im2arr, (2, 0, 1))
en Formato CxHxW.
Necesita convertir su imagen a una matriz numpy de esta manera:
import numpy
import PIL
img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img)
No está diciendo exactamente cómo putdata()
no se está comportando. Supongo que 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 es porque putdata
espera una secuencia de tuplas y le estás dando una matriz numpy. Esta
>>> 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 "correcta" de convertir imágenes y matrices numpy es simplemente
>>> pix = numpy.array(pic)
aunque la matriz resultante tiene un formato diferente al tuyo (matriz 3-d o filas / columnas / rgb en este caso).
Luego, después de realizar los cambios en la matriz, debería poder hacer pic.putdata(pix)
o crear una nueva imagen con Image.fromarray(pix)
.