web-dev-qa-db-fra.com

Comment convertir une image PIL dans un tableau numpy?

Très bien, je m'emploie à convertir un objet-image PIL en un tableau numpy afin de pouvoir effectuer des transformations pixel par pixel plus rapides que ne le permettait l'objet PixelAccess de PIL. J'ai compris comment placer les informations de pixel dans un tableau numpy 3D utile à l'aide de:

pic = Image.open("foo.jpg")
pix = numpy.array(pic.getdata()).reshape(pic.size[0], pic.size[1], 3)

Mais je n'arrive pas à comprendre comment le réintégrer dans l'objet PIL après avoir effectué toutes mes transformations géniales. Je suis conscient de la méthodeputdata(), mais je n'arrive pas à comprendre comment elle se comporte.

156
akdom

Vous ne dites pas comment exactement putdata() ne se comporte pas. Je suppose que vous faites 

>>> 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

En effet, putdata attend une séquence de tuples et vous lui attribuez un tableau numpy. Ce

>>> data = list(Tuple(pixel) for pixel in pix)
>>> pic.putdata(data)

fonctionnera mais c’est très lent. 

A partir de PIL 1.1.6, le "bon" moyen de convertir des images en tableaux numpy est tout simplement

>>> pix = numpy.array(pic)

bien que le tableau résultant soit dans un format différent du vôtre (tableau à trois dimensions ou lignes/colonnes/rgb dans ce cas).

Ensuite, après avoir apporté vos modifications au tableau, vous devriez être en mesure de faire pic.putdata(pix) ou de créer une nouvelle image avec Image.fromarray(pix)

191
dF.

Ouvrez I en tant que tableau:

>>> I = numpy.asarray(PIL.Image.open('test.jpg'))

Faites des trucs pour I, puis reconvertissez-le en image:

>>> im = PIL.Image.fromarray(numpy.uint8(I))

Filtrer les images numpy avec FFT, Python

Si vous voulez le faire explicitement pour une raison quelconque, il existe des fonctions pil2array () et array2pil () qui utilisent getdata () sur cette page dans correlation.Zip.

138
endolith

J'utilise Pillow 4.1.1 (le successeur de PIL) dans Python 3.5. La conversion entre Pillow et Numpy est simple. 

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)

Une chose à noter est que im de style Pillow est majeur en colonnes tandis que im2arr de style numpy est majeur en lignes. Cependant, la fonction Image.fromarray en tient déjà compte. C'est-à-dire arr2im.size == im.size et arr2im.mode == im.mode dans l'exemple ci-dessus. 

Nous devons nous occuper du format de données HxWxC lors du traitement des tableaux numpy transformés, par exemple. faire la transformation im2arr = np.rollaxis(im2arr, 2, 0) ou im2arr = np.transpose(im2arr, (2, 0, 1)) au format CxHxW.

44
Daniel

Vous devez convertir votre image en tableau numpy de cette façon:

import numpy
import PIL

img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img) 
10
Billal Begueradj

L'exemple que j'ai utilisé aujourd'hui:

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)
3
Uki D. Lucas

Si votre image est stockée au format Blob (c'est-à-dire dans une base de données), vous pouvez utiliser la même technique que celle expliquée par Billal Begueradj pour convertir votre image de Blobs en tableau d'octets.

Dans mon cas, j'avais besoin que mes images soient stockées dans une colonne blob dans une table de base de données:

def select_all_X_values(conn):
    cur = conn.cursor()
    cur.execute("SELECT ImageData from PiecesTable")    
    rows = cur.fetchall()    
    return rows

J'ai ensuite créé une fonction d'assistance pour changer mon ensemble de données en np.array:

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

Après cela, j'ai pu utiliser les byteArrays de mon réseau de neurones.

plt.imshow(imagesList[0])
0
Charles Vogt
def imshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()

Vous pouvez transformer l’image en numpy en l’analysant en fonction numpy () après avoir supprimé les fonctionnalités

0
Thiyagu