Pergunta

Tudo bem, eu estou brincando ao redor com a conversão de um objeto de imagem PIL e para trás em uma matriz de numpy para que eu possa fazer alguma pixels mais rápido por transformações de pixel de objeto PixelAccess do PIL permitiria. Eu descobri como colocar as informações de pixel em uma matriz útil numpy 3D por meio de:

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

Mas eu não consigo descobrir como carregá-lo de volta para o objeto PIL depois que eu fiz todas as minhas transformações impressionantes. Estou ciente do putdata() método, mas não consegue parecem se ele se comportar.

Foi útil?

Solução

Você não está dizendo exatamente como putdata() não está se comportando. Estou assumindo que você está fazendo

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

Isto porque putdata espera uma seqüência de tuplas e você está dando-lhe uma matriz numpy. Este

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

vai funcionar, mas é muito lento.

A partir de PIL 1.1.6, o "adequada" maneira de converter entre imagens e numpy matrizes é simplesmente

>>> pix = numpy.array(pic)

embora a matriz resultante é de um formato diferente do que o seu (3-d matriz ou linhas / colunas / RGB neste caso).

Então, depois de fazer as alterações para a matriz, você deve ser capaz de fazer qualquer um pic.putdata(pix) ou criar uma nova imagem com Image.fromarray(pix).

Outras dicas

Open I como uma matriz:

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

Faça alguma coisa para I, em seguida, convertê-lo de volta para uma imagem:

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

imagens numpy filtro com FFT, Python

Se você quiser fazê-lo explicitamente, por algum motivo, há pil2array () e array2pil () funções usando getdata () em desta página em correlation.zip.

Eu estou usando Pillow 4.1.1 (o sucessor do PIL) em Python 3.5. A conversão entre Pillow e numpy é simples.

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)

Uma coisa que precisa perceber é que im Pillow-estilo é a coluna-major enquanto im2arr-style numpy é da maior linha. No entanto, a função Image.fromarray já leva isso em consideração. Ou seja, arr2im.size == im.size e arr2im.mode == im.mode no exemplo acima.

Devemos cuidar do formato de dados HxWxC ao processar as matrizes numpy transformados, por exemplo, faça o im2arr = np.rollaxis(im2arr, 2, 0) ou im2arr = np.transpose(im2arr, (2, 0, 1)) transformar em formato CxHxW.

Você precisa converter sua imagem para uma matriz numpy desta maneira:

import numpy
import PIL

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

O exemplo, tenho usado hoje:

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)

Se a imagem é armazenada em um formato Blob (ou seja, em um banco de dados), você pode usar a mesma técnica explicada por Billal Begueradj para converter sua imagem de Blobs para um array de bytes.

No meu caso, eu precisava de minhas imagens onde armazenados em uma coluna blob em uma tabela db:

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

Então, criamos uma função auxiliar para mudar o meu conjunto de dados em 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

Depois disso, eu era capaz de usar os bytearrays na minha rede neural.

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

Você pode transformar a imagem em numpy analisando a imagem em numpy () função depois espremendo para fora as características (unnormalization)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top