web-dev-qa-db-fra.com

Image PIL à tableau (tableau numpy à tableau) - Python

J'ai une image .jpg que je voudrais convertir en tableau Python, car j'ai implémenté des routines de traitement gérant des tableaux Python simples. 

Il semble que les images PIL supportent la conversion en numpy array, et selon la documentation, j'ai écrit ceci:

from PIL import Image
im = Image.open("D:\Prototype\Bikesgray.jpg")
im.show()

print(list(np.asarray(im)))

Ceci retourne une liste de tableaux numpy. Aussi, j'ai essayé avec 

list([list(x) for x in np.asarray(im)])

ce qui ne retourne rien du tout puisqu'il échoue.

Comment puis-je convertir de PIL en tableau, ou simplement de numpy tableau en tableau Python?

14
octoback

Je pense que ce que vous recherchez, c'est:

list(im.getdata())

ou, si l'image est trop grande pour être chargée entièrement en mémoire, quelque chose comme ça:

for pixel in iter(im.getdata()):
    print pixel

à partir de documentation PIL :

getdata

im.getdata () => séquence

Renvoie le contenu d'une image sous forme d'objet de séquence contenant le pixel valeurs. L'objet de séquence est aplati, de sorte que les valeurs de la première ligne suivez directement les valeurs de la ligne zéro, et ainsi de suite.

Notez que l'objet séquence renvoyé par cette méthode est un interne Type de données PIL, qui ne prend en charge que certaines opérations de séquence, y compris l'itération et l'accès à la séquence de base. Pour le convertir en séquence ordinaire (par exemple pour l’impression), utilisez list (im.getdata ()).

12
zenpoy

Je vous recommande vivement d'utiliser la fonction tobytes de l'objet Image. Après quelques vérifications, c'est beaucoup plus efficace.

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

Les timings j'ai couru sur mon spectacle d'ordinateur portable

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

Basé sur la réponse de zenpoy :

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

J'utilise numpy.fromiter pour inverser un bitmap à 8 niveaux de gris, mais aucun signe d'effet secondaire

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