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.
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.
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.
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.
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)
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)
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])
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).