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