Jak przekonwertować tablicę numpy na (i wyświetlić) obraz?

227

W ten sposób utworzyłem tablicę:

import numpy as np
data = np.zeros( (512,512,3), dtype=np.uint8)
data[256,256] = [255,0,0]

Chcę to zrobić, aby wyświetlić pojedynczą czerwoną kropkę na środku obrazu 512x512. (Przynajmniej na początek ... Myślę, że mogę dowiedzieć się reszty stamtąd)

jlswint
źródło
1
Zobacz także stackoverflow.com/questions/902761/... chociaż ten narzucił ograniczenie, że nie można użyć PIL.
Peter Hansen
Czy możesz rozważyć zmianę zaakceptowanej odpowiedzi na odpowiedź Piotra ? Pozwala to uniknąć konieczności owijania obiektu wokół tablicy numpy i pozwala uniknąć pisania pliku tymczasowego w celu wyświetlenia obrazu.
Josiah Yoder

Odpowiedzi:

224

Możesz użyć PIL do utworzenia (i wyświetlenia) obrazu:

from PIL import Image
import numpy as np

w, h = 512, 512
data = np.zeros((h, w, 3), dtype=np.uint8)
data[0:256, 0:256] = [255, 0, 0] # red patch in upper left
img = Image.fromarray(data, 'RGB')
img.save('my.png')
img.show()
unutbu
źródło
3
Wygląda na to, że wystąpił błąd. Tworzysz tablicę o rozmiarze (w,h,3), ale tak powinno być (h,w,3), ponieważ indeksowanie w PIL różni się od indeksowania w numpy. Powiązane pytanie: stackoverflow.com/questions/33725237/…
fdermishin
1
@ user502144: Dziękujemy za zwrócenie uwagi na mój błąd. Powinienem był stworzyć tablicę kształtów (h,w,3). (Teraz jest to ustalone powyżej). Długość pierwszej osi może być traktowana jako liczba wierszy w tablicy, a długość drugiej osi - liczba kolumn. (h, w)Odpowiada więc tablicy „wysokość” hi „szerokość” w. Image.fromarraykonwertuje tę tablicę na obraz wysokości hi szerokości w.
unutbu,
1
img.show()nie działają w notatniku ipython. img_pil = Image.fromarray(img, 'RGB') display(img_pil.resize((256,256), PIL.Image.LANCZOS))
mrgloom
@unutbu ta metoda wydaje się zniekształcać obrazy ... stackoverflow.com/questions/62293077/…
Ludovico Verniani
284

Następujące powinny działać:

from matplotlib import pyplot as plt
plt.imshow(data, interpolation='nearest')
plt.show()

Jeśli używasz notesu / laboratorium Jupyter, użyj tego polecenia inline przed importowaniem matplotlib:

%matplotlib inline 
Steve Tjoa
źródło
3
Jest to dokładniejsze niż PIL. PIL przeskalowuje / normalizuje wartości tablic, podczas gdy pyplot używa rzeczywistych wartości RGB takimi, jakie są.
GaryO
21
Być może warto wiedzieć: jeśli chcesz wyświetlać obrazy w skali szarości, zaleca się plt.gray()jednorazowe wywołanie kodu, aby przełączyć wszystkie kolejne wykresy na skalę szarości. Nie tego, czego chce OP, ale mimo to dobrze wiedzieć.
Cerno
2
Jak to zapisać?
user334639,
Plik „<ipython-input-29-29c784f62838>”, wiersz 39 plt.show () ^ Błąd składni: nieprawidłowa składnia
Mona Jalal
1
@Cerno Ponadto obrazy w skali szarości powinny mieć kształt (h, w), a nie (h, w, 1). Możesz użyć squeeze()do wyeliminowania trzeciego wymiaru:plt.imshow(data.squeeze())
Josiah Yoder
51

Najkrótszą ścieżką jest użycie scipy:

from scipy.misc import toimage
toimage(data).show()

Wymaga to również zainstalowania PIL lub Pillow.

Podobne podejście wymagające również PIL lub Pillow, ale które może wywołać innego widza :

from scipy.misc import imshow
imshow(data)
Peter Hansen
źródło
Więc ta metoda jest niezgodna z python 3.5 ...?
Christopher
@bordeo, dlaczego miałby być niezgodny z 3.5? To tylko import i kilka wywołań funkcji.
Peter Hansen
PIL jest niezgodny z wersją 3.5 (nie chce się zainstalować)
Christopher
1
Ftr: możesz to jeszcze bardziej skrócić, używając bezpośrednio scipy.misc.imshow(data).
dtk,
3
toimagezostał przestarzały w scipy-1.0.0 i usunięty w 1.2.0 na korzyść Pillow's Image.fromarray.
Sid
4

Korzystając z pygame , możesz otworzyć okno, uzyskać powierzchnię jako układ pikseli i manipulować stamtąd, jak chcesz. Musisz jednak skopiować tablicę numpy do tablicy powierzchni, co będzie znacznie wolniejsze niż wykonywanie rzeczywistych operacji graficznych na samych powierzchniach gry.

Stefan Kendall
źródło
3

Jak wyświetlać obrazy zapisane w tablicy numpy na przykładzie (działa w notatniku Jupyter)

Wiem, że są prostsze odpowiedzi, ale ta pozwoli ci zrozumieć, w jaki sposób obrazy są faktycznie topione z tablicy numpy.

Załaduj przykład

from sklearn.datasets import load_digits
digits = load_digits()
digits.images.shape   #this will give you (1797, 8, 8). 1797 images, each 8 x 8 in size

Wyświetl tablicę jednego obrazu

digits.images[0]
array([[ 0.,  0.,  5., 13.,  9.,  1.,  0.,  0.],
       [ 0.,  0., 13., 15., 10., 15.,  5.,  0.],
       [ 0.,  3., 15.,  2.,  0., 11.,  8.,  0.],
       [ 0.,  4., 12.,  0.,  0.,  8.,  8.,  0.],
       [ 0.,  5.,  8.,  0.,  0.,  9.,  8.,  0.],
       [ 0.,  4., 11.,  0.,  1., 12.,  7.,  0.],
       [ 0.,  2., 14.,  5., 10., 12.,  0.,  0.],
       [ 0.,  0.,  6., 13., 10.,  0.,  0.,  0.]])

Utwórz puste 10 x 10 podplotów w celu wizualizacji 100 zdjęć

import matplotlib.pyplot as plt
fig, axes = plt.subplots(10,10, figsize=(8,8))

Rysowanie 100 zdjęć

for i,ax in enumerate(axes.flat):
    ax.imshow(digits.images[i])

Wynik:

wprowadź opis zdjęcia tutaj

Co ma axes.flatzrobić? Tworzy moduł wyliczający numpy, dzięki czemu można iterować po osi w celu rysowania na nich obiektów. Przykład:

import numpy as np
x = np.arange(6).reshape(2,3)
x.flat
for item in (x.flat):
    print (item, end=' ')
Harvey
źródło
2

Korzystając z tablicy poduszek, na przykład:

from PIL import Image
from numpy import *

im = array(Image.open('image.jpg'))
Image.fromarray(im).show()
użytkownik3322286
źródło
0

Dodatek za zrobienie tego z matplotlib. Uznałem, że jest to przydatne przy wykonywaniu zadań związanych z wizją komputera. Powiedzmy, że masz dane z dtype = int32

from matplotlib import pyplot as plot
import numpy as np

fig = plot.figure()
ax = fig.add_subplot(1, 1, 1)
# make sure your data is in H W C, otherwise you can change it by
# data = data.transpose((_, _, _))
data = np.zeros((512,512,3), dtype=np.int32)
data[256,256] = [255,0,0]
ax.imshow(data.astype(np.uint8))
użytkownik140536
źródło