Domanda

Va bene, sto giocando con la conversione di un oggetto immagine PIL avanti e indietro in un array numpy in modo da poter eseguire trasformazioni pixel per pixel più veloci rispetto a PIL PixelAccess l'oggetto consentirebbe.Ho capito come posizionare le informazioni sui pixel in un utile array numpy 3D tramite:

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

Ma non riesco a capire come caricarlo nuovamente nell'oggetto PIL dopo aver eseguito tutte le mie fantastiche trasformazioni.Sono a conoscenza del putdata() metodo, ma non riesco proprio a farlo funzionare.

È stato utile?

Soluzione

Non stai dicendo come esattamente putdata() non si comporta. Sto assumendo che stai facendo

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

Questo perché putdata si aspetta una sequenza di tuple e si sta dando una matrice NumPy. Questo

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

funzionerà, ma è molto lento.

A partire dal PIL 1.1.6, il href="http://effbot.org/zone/pil-changes-116.htm" modo "corretto" per la conversione tra immagini e numpy array è semplicemente

>>> pix = numpy.array(pic)

anche se la matrice risultante è in un formato diverso rispetto tua (3-d array o righe / colonne / rgb in questo caso).

Poi, dopo aver apportato le modifiche alla matrice, si dovrebbe essere in grado di fare sia pic.putdata(pix) o creare una nuova immagine con Image.fromarray(pix).

Altri suggerimenti

Aprire I come un array:

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

Fai qualcosa per I, quindi riconvertirlo in un'immagine:

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

Filtra immagini Numpy con FFT, Python

Se vuoi farlo esplicitamente per qualche motivo, ci sono le funzioni pil2array() e array2pil() che usano getdata() su questa pagina in correlazione.zip.

Sto usando il cuscino 4.1.1 (il successore di PIL) in Python 3.5. La conversione tra il cuscino e NumPy è semplice.

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 che deve notare è che in stile cuscino im è column-major, mentre NumPy stile im2arr è row-major. Tuttavia, la funzione Image.fromarray tiene già in considerazione questo. Cioè, arr2im.size == im.size e arr2im.mode == im.mode nell'esempio precedente.

Dobbiamo curare il formato dati HxWxC quando elabora i matrici NumPy trasformate, ad esempio effettuare le im2arr = np.rollaxis(im2arr, 2, 0) o im2arr = np.transpose(im2arr, (2, 0, 1)) la trasformazione in forma CxHxW.

È necessario convertire l'immagine in un array di NumPy in questo modo:

import numpy
import PIL

img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img) 

L'esempio che ho usato oggi:

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)

Se l'immagine viene memorizzata in un formato di Blob (vale a dire in un database) è possibile utilizzare la stessa tecnica spiegata da Billal Begueradj per convertire l'immagine da Blobs a un array di byte.

Nel mio caso, avevo bisogno di mie immagini in cui memorizzate in una colonna BLOB in una tabella db:

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

Poi ho creato una funzione di supporto per cambiare il mio insieme di dati in 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

Dopo questo, sono stato in grado di utilizzare le bytearrays nella mia rete neurale.

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

È possibile trasformare l'immagine in numpy analizzando l'immagine in NumPy () funzione dopo schiacciamento le caratteristiche (unnormalization)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top