Jak przekonwertować obraz PIL na tablicę numpy?

W porządku, bawię się konwertowaniem obiektu obrazu pil tam i z powrotem do tablicy numpy, więc mogę wykonać kilka szybszych przekształceń piksel po pikselu niż obiekt PixelAccess pil by pozwolił. Udało mi się umieścić informacje o pikselach w użytecznej tablicy numpy 3D w następujący sposób:

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

Ale nie wiem, jak załadować go z powrotem do obiektu PIL po wykonaniu wszystkich moich niesamowitych przekształceń. Jestem świadomy putdata() metoda, ale nie wydaje się, aby uzyskać go do zachowuj się.

Author: martineau, 2008-12-21

5 answers

Nie mówisz, jak dokładnie putdata() nie zachowuje się. Zakładam, że robisz

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

Dzieje się tak dlatego, że putdata oczekuje sekwencji krotek, a Ty dajesz jej tablicę numpy. To

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

Będzie działać, ale jest bardzo powolny.

Od PIL 1.1.6, "właściwym" sposobem konwersji pomiędzy obrazami i tablicami numpy jest po prostu

>>> pix = numpy.array(pic)

Chociaż wynikowa tablica jest w innym formacie niż Twoja (tablica 3-d lub wiersze / kolumny / rgb w tym case).

Następnie, po wprowadzeniu zmian w tablicy, powinieneś być w stanie wykonać pic.putdata(pix) lub utworzyć nowy obraz za pomocą Image.fromarray(pix).

 168
Author: dF.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-29 11:11:48

Otwórz I jako tablicę:

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

Zrób kilka rzeczy do I, a następnie przekonwertuj je z powrotem na obraz:

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

Filtruj obrazy numpy za pomocą FFT, Python

Jeśli chcesz to zrobić jawnie z jakiegoś powodu, istnieją funkcje pil2array() i array2pil() używające getdata() na tej stronie w korelacji.zip.

 121
Author: endolith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-23 15:29:13

Używam Pillow 4.1.1 (następca PIL) w Pythonie 3.5. Konwersja pomiędzy Pillow i numpy jest prosta.

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)

Należy zauważyć, że styl poduszkowy im to kolumna-dur, podczas gdy numpy-styl im2arr to wiersz-dur. Jednak funkcja Image.fromarray bierze to już pod uwagę. Czyli arr2im.size == im.size i arr2im.mode == im.mode w powyższym przykładzie.

Przy przetwarzaniu przekształconych tablic numpy powinniśmy zadbać o format danych HxWxC, np. czy przekształć im2arr = np.rollaxis(im2arr, 2, 0) lub im2arr = np.transpose(im2arr, (2, 0, 1)) W format CxHxW.

 27
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-26 10:14:17

Musisz przekonwertować obraz na tablicę numpy w ten sposób:

import numpy
import PIL

img = PIL.Image.open("foo.jpg").convert("L")
imgarr = numpy.array(img) 
 6
Author: Billal Begueradj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-07 09:18:59

Przykład, którego użyłem dzisiaj:

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)
 2
Author: Uki D. Lucas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-03 20:53:06