Pregunta

Muy bien, estoy jugando con la conversión de un objeto de imagen PIL de un lado a otro en una matriz numpy para poder hacer transformaciones píxel por píxel más rápidas que las de PIL. PixelAccess objeto lo permitiría.Descubrí cómo colocar la información de píxeles en una matriz numpy 3D útil mediante:

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

Pero parece que no puedo entender cómo volver a cargarlo en el objeto PIL después de haber realizado todas mis increíbles transformaciones.soy consciente de la putdata() método, pero parece que no puedo lograr que se comporte.

¿Fue útil?

Solución

No estás diciendo exactamente cómo putdata() no se está comportando.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 es porque 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, el forma "adecuada" de convertir entre imágenes y matrices numerosas es simple

>>> 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 hacer ambas cosas: pic.putdata(pix) o crear una nueva imagen con Image.fromarray(pix).

Otros consejos

I Abrir como una matriz:

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

Hacer algunas cosas para I, a continuación, volver a convertirlo en una imagen:

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

Filtro numpy imágenes con FFT, Python

Si desea hacerlo de forma explícita, por alguna razón, hay pil2array () y array2pil () funciona utilizando leedato () en esta página en correlation.zip.

Estoy utilizando Almohada 4.1.1 (el sucesor del PIL) en Python 3.5. La conversión entre la almohadilla y numpy es sencillo.

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 notar es que im de estilo almohada es la columna-principal, mientras que im2arr de estilo numpy es de las filas. Sin embargo, la función ya Image.fromarray toma esto en consideración. Es decir, arr2im.size == im.size y arr2im.mode == im.mode en el ejemplo anterior.

Hay que cuidar el formato de datos HxWxC al procesar las matrices numpy transformadas, por ejemplo, haga lo im2arr = np.rollaxis(im2arr, 2, 0) o im2arr = np.transpose(im2arr, (2, 0, 1)) transformarse en formato CxHxW.

Es necesario para 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) 

El ejemplo, he utilizado en la actualidad:

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)

Si la imagen se almacena en un formato Blob (es decir, en una base de datos), puede utilizar la misma técnica explicada por Billal Begueradj para convertir su imagen de gotas a una matriz de bytes.

En mi caso, necesitaba mis imágenes donde almacenan en una columna BLOB en una tabla db:

def select_all_X_values(conn):
    cur = conn.cursor()
    cur.execute("SELECT ImageData from PiecesTable")    
    rows = cur.fetchall()    
    return rows

Entonces creé una función de ayuda para cambiar mi conjunto de datos en np.array:

X_dataset = select_all_X_values(conn)
imagesList = convertToByteIO(np.array(X_dataset))

def convertToByteIO(imagesArray):
    """
    # Converts an array of images into an array of Bytes
    """
    imagesList = []

    for i in range(len(imagesArray)):  
        img = Image.open(BytesIO(imagesArray[i])).convert("RGB")
        imagesList.insert(i, np.array(img))

    return imagesList

Después de esto, yo era capaz de utilizar las byteArrays en mi red neuronal.

plt.imshow(imagesList[0])
def imshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()

Usted puede transformar la imagen en numpy mediante el análisis de la imagen en numpy () la función después de aplastar a cabo las características (unnormalization)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top