it-swarm.com.de

PIL-Bild zu Array (numpy Array zu Array) - Python

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?

14
octoback

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

12
zenpoy

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

`` `

17
awnihannun

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
5
Martin Thoma

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