Wie ein PIL Bild in eine numpy Array konvertieren?
-
23-08-2019 - |
Frage
In Ordnung, ich bin Herumspielen ein PIL Bildobjekt hin und her zu einem numpy Array mit der Umwandlung so dass ich von Pixel Transformationen als PIL PixelAccess
Objekt erlauben würde, einige schnellere Pixel tun können. Ich habe herausgefunden, wie die Pixelinformation in einem nützlichen 3D numpy Array platziert haft:
pic = Image.open("foo.jpg")
pix = numpy.array(pic.getdata()).reshape(pic.size[0], pic.size[1], 3)
Aber ich kann nicht scheinen, um herauszufinden, wie es in das PIL Objekt wieder zu laden, nachdem ich all meine ehrfürchtigen Transformationen getan habe. Ich bin mir bewusst, der putdata()
Methode, kann aber nicht ganz scheinen, um es zu bekommen zu verhalten.
Lösung
Sie sagen, nicht, wie genau putdata()
verhält sich nicht. Ich gehe davon aus Sie tun
>>> 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
Das ist, weil putdata
eine Sequenz von Tupeln erwartet und Sie ihm eine numpy Array sind zu geben. Diese
>>> data = list(tuple(pixel) for pixel in pix)
>>> pic.putdata(data)
funktioniert, aber es ist sehr langsam.
Wie von PIL 1.1.6, die „richtige“ Art und Weise zwischen den Bildern und numpy zu konvertieren Arrays ist einfach
>>> pix = numpy.array(pic)
Obwohl das resultierende Array ist in einem anderen Format als verkaufen (3-D-Array oder Zeilen / Spalten / RGB in diesem Fall).
Dann, nachdem Sie Ihre Änderungen an der Reihe zu machen, sollten Sie in der Lage sein, entweder pic.putdata(pix)
zu tun oder ein neues Bild mit Image.fromarray(pix)
erstellen.
Andere Tipps
Öffnen I
als Array:
>>> I = numpy.asarray(PIL.Image.open('test.jpg'))
ein paar Sachen tun I
, dann wandelt sie zurück in ein Bild:
>>> im = PIL.Image.fromarray(numpy.uint8(I))
Filter numpy Bilder mit FFT, Python
Wenn Sie es explizit aus irgendeinem Grund tun wollen, gibt es pil2array () und array2pil () Funktionen getdata () auf diese Seite in correlation.zip.
Ich bin mit Kissen 4.1.1 (der Nachfolger von PIL) in Python 3.5. Die Umwandlung 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)
Eine Sache, die Bemerken muss, ist, dass Pillow-Stil im
ist column-Dur während numpy-Stil im2arr
Reihe-Dur. Allerdings nimmt die Funktion Image.fromarray
dies bereits berücksichtigt. Das heißt, arr2im.size == im.size
und arr2im.mode == im.mode
in dem obigen Beispiel.
Wir sollten kümmern sich um die HxWxC Datenformat, wenn die transformierten numpy Arrays Verarbeitung, z.B. Sie die Transformation im2arr = np.rollaxis(im2arr, 2, 0)
oder im2arr = np.transpose(im2arr, (2, 0, 1))
in CxHxW Format.
Sie müssen Ihr Bild auf eine numpy Array auf diese Weise 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 gespeichert (das heißt in einer Datenbank) Sie die gleiche Technik, die von Billal Begueradj erklärte verwenden können Ihr Bild von Blobs zu einer Byte-Array zu konvertieren.
In meinem Fall musste ich meine Bilder, in denen in einer BLOB-Spalte in einer Tabelle db gespeichert:
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 meine Daten-Sets 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 Neural Network 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 numpy verwandeln durch das Bild in numpy Parsen () Funktion nach den Merkmalen squishing aus (unnormalization)