Ich habe ein JPG-Bild, das ich in ein Python-Array konvertieren möchte, weil ich Behandlungsroutinen implementiert habe, die nur Python-Arrays verwenden.
Es scheint, dass PIL-Images die Konvertierung in ein Numpy-Array unterstützen, und der Dokumentation zufolge habe ich Folgendes geschrieben:
from PIL import Image
im = Image.open("D:\Prototype\Bikesgray.jpg")
im.show()
print(list(np.asarray(im)))
Dies gibt eine Liste von Numpy-Arrays zurück. Ich habe es auch mit versucht
list([list(x) for x in np.asarray(im)])
was nichts zurückgibt, da es versagt.
Wie kann ich von PIL in ein Array oder einfach von einem Numpy-Array in ein Python-Array konvertieren?
Ich denke, was Sie suchen, ist:
list(im.getdata())
oder, wenn das Bild zu groß ist, um vollständig in den Speicher geladen zu werden, so etwas wie das:
for pixel in iter(im.getdata()):
print pixel
aus PIL Dokumentation :
daten empfangen
im.getdata () => Sequenz
Gibt den Inhalt eines Bildes als Sequenzobjekt zurück, das Pixel enthält Werte. Das Sequenzobjekt ist abgeflacht, sodass die Werte für Zeile Eins folgt direkt nach den Werten der Zeile Null und so weiter.
Beachten Sie, dass das von dieser Methode zurückgegebene Sequenzobjekt ein internes .__ ist. PIL-Datentyp, der nur bestimmte Sequenzoperationen unterstützt, einschließlich Iteration und grundlegender Sequenzzugriff. So konvertieren Sie es in eine gewöhnliche Reihenfolge (z. B. zum Drucken), use list (im.getdata ()).
Ich empfehle Ihnen dringend, die tobytes
-Funktion des Image
-Objekts zu verwenden. Nach einigen Timing-Checks ist dies viel effizienter.
def jpg_image_to_array(image_path):
"""
Loads JPEG image into 3D Numpy array of shape
(width, height, channels)
"""
with Image.open(image_path) as image:
im_arr = np.fromstring(image.tobytes(), dtype=np.uint8)
im_arr = im_arr.reshape((image.size[1], image.size[0], 3))
return im_arr
Die Zeiten, die ich auf meinem Laptop lief, zeigen
In [76]: %timeit np.fromstring(im.tobytes(), dtype=np.uint8)
1000 loops, best of 3: 230 µs per loop
In [77]: %timeit np.array(im.getdata(), dtype=np.uint8)
10 loops, best of 3: 114 ms per loop
`` `
Basierend auf zenpoys Antwort :
import Image
import numpy
def image2pixelarray(filepath):
"""
Parameters
----------
filepath : str
Path to an image file
Returns
-------
list
A list of lists which make it simple to access the greyscale value by
im[y][x]
"""
im = Image.open(filepath).convert('L')
(width, height) = im.size
greyscale_map = list(im.getdata())
greyscale_map = numpy.array(greyscale_map)
greyscale_map = greyscale_map.reshape((height, width))
return greyscale_map
Ich verwende numpy.fromiter, um eine 8-Graustufen-Bitmap zu invertieren, jedoch keine Anzeichen von Nebenwirkungen
import Image
import numpy as np
im = Image.load('foo.jpg')
im = im.convert('L')
arr = np.fromiter(iter(im.getdata()), np.uint8)
arr.resize(im.height, im.width)
arr ^= 0xFF # invert
inverted_im = Image.fromarray(arr, mode='L')
inverted_im.show()