Question

D'accord, je suis autour de convertir jouant un objet image PIL et-vient à un tableau numpy pour que je puisse faire quelques pixels plus rapidement par des transformations de pixels que l'objet PixelAccess de PIL permettrait. J'ai compris comment placer les informations de pixels dans un tableau numpy 3D utile par le biais de:

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

Mais je ne peux pas sembler comprendre comment le charger de nouveau dans l'objet PIL après que je l'ai fait toutes mes transformations impressionnantes. Je suis au courant de la putdata() méthode, mais ne peut pas sembler tout à fait pour l'obtenir se comporter.

Était-ce utile?

La solution

Vous ne dites pas exactement comment 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 triplets et vous donnez un tableau numpy. Ce

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

fonctionne, mais il est très lent.

Au PIL 1.1.6, le façon "appropriée" pour convertir entre les images et numpy tableaux est simplement

>>> pix = numpy.array(pic)

bien que la matrice résultante est sous une forme différente de la vôtre (tableau 3-d ou rangées / colonnes / rgb dans ce cas).

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

Autres conseils

Ouvrir I comme un tableau:

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

Faites des choses à I, puis, reconvertir en une image:

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

Filtre numpy images avec FFT, python

Si vous voulez le faire explicitement pour une raison quelconque, il y a pil2array () et array2pil () à l'aide getdata () sur cette page correlation.zip.

J'utilise Pillow 4.1.1 (le successeur de PIL) en 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 qui a besoin rende compte est que im style oreiller est colonne-major tout im2arr numpy style est rangée-major. Cependant, la fonction Image.fromarray prend déjà cela en considération. Autrement dit, arr2im.size == im.size et arr2im.mode == im.mode dans l'exemple ci-dessus.

Nous devons prendre soin du format de données HxWxC lors du traitement des matrices de numpy transformées, par exemple la transformation ne im2arr = np.rollaxis(im2arr, 2, 0) ou im2arr = np.transpose(im2arr, (2, 0, 1)) au format CxHxW.

Vous devez convertir votre image à un tableau numpy cette façon:

import numpy
import PIL

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

L'exemple, je l'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 dans un format de Blob (par exemple dans une base de données), vous pouvez utiliser la même technique expliquée par Billal Begueradj pour convertir votre image de Blobs à un tableau d'octets.

Dans mon cas, je besoin de mes images où stockées dans une colonne de blob dans une table db:

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'aide pour changer mon jeu 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 dans 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 analysant l'image en fonction numpy () après squishing les caractéristiques (unnormalization)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top