it-swarm.com.de

Wie konvertiere ich ein PIL-Bild in ein numpy-Array?

In Ordnung, ich spiele mit dem Konvertieren eines PIL-Bildobjekts in ein numpy-Array herum, so dass ich einige Pixel für Pixel-Transformationen schneller durchführen kann, als das PixelAccess-Objekt von PIL. Ich habe herausgefunden, wie man die Pixelinformationen in einem nützlichen 3D-Array mit Hilfe von:

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

Ich kann jedoch nicht herausfinden, wie ich es zurück in das PIL-Objekt laden kann, nachdem ich alle meine fantastischen Transformationen durchgeführt habe. Ich kenne dieputdata()-Methode, kann mich aber nicht recht dazu bringen, dass sie sich benimmt.

156
akdom

Sie sagen nicht, wie genau sich putdata() nicht verhält. Ich gehe davon aus, dass du es tust 

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

Dies liegt daran, dass putdata eine Folge von Tupeln erwartet und Sie ein numpy-Array angeben. Diese

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

wird funktionieren, aber es ist sehr langsam. 

Seit PIL 1.1.6 ist der "richtige" Weg zum Konvertieren zwischen Bildern und numpy-Arrays einfach

>>> pix = numpy.array(pic)

das resultierende Array hat jedoch ein anderes Format als Ihr Format (in diesem Fall 3-D-Array oder Zeilen/Spalten/RGB).

Nachdem Sie die Änderungen am Array vorgenommen haben, sollten Sie entweder pic.putdata(pix) ausführen oder ein neues Bild mit Image.fromarray(pix) erstellen. 

191
dF.

I als Array öffnen:

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

Tun Sie etwas zu I und konvertieren Sie es zurück in ein Bild:

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

Filtern Sie numpy Bilder mit FFT, Python

Wenn Sie dies aus irgendeinem Grund explizit tun möchten, gibt es pil2array () - und array2pil () - Funktionen, die getdata () auf dieser Seite in correlation.Zip verwenden.

138
endolith

Ich benutze Pillow 4.1.1 (den Nachfolger von PIL) in Python 3.5. Die Umstellung zwischen Kissen und Numpy ist unkompliziert. 

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)

Was zu beachten ist, ist, dass der Pillow-Stil im die größte Spalte ist, während der numpy-Stil im2arr der Zeilen-Major ist. Die Funktion Image.fromarray berücksichtigt dies jedoch bereits. Das heißt, arr2im.size == im.size und arr2im.mode == im.mode im obigen Beispiel. 

Bei der Verarbeitung der transformierten Numpy-Arrays, z. Führen Sie die Transformation im2arr = np.rollaxis(im2arr, 2, 0) oder im2arr = np.transpose(im2arr, (2, 0, 1)) in das CxHxW-Format aus.

44
Daniel

Sie müssen Ihr Bild auf diese Weise in ein numpy-Array konvertieren:

import numpy
import PIL

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

Das Beispiel habe ich heute verwendet:

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)
3
Uki D. Lucas

Wenn Ihr Bild in einem Blob-Format (d. H. In einer Datenbank) gespeichert ist, können Sie dasselbe von Billal Begueradj beschriebene Verfahren verwenden, um Ihr Bild von Blobs in ein Byte-Array zu konvertieren.

In meinem Fall brauchte ich meine Bilder in einer Blob-Spalte in einer Db-Tabelle:

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

Ich habe dann eine Hilfsfunktion erstellt, um mein Dataset in np.array zu ändern:

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

Danach konnte ich die ByteArrays in meinem neuronalen Netzwerk verwenden.

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

Sie können das Bild in eine Zahl verwandeln, indem Sie es nach dem Ausblenden der Merkmale in die Funktion numpy () zerlegen (unnormalization).

0
Thiyagu