Come faccio a convertire un array numpy in (e visualizzare) un'immagine?


228

Ho creato così un array:

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

Quello che voglio fare è visualizzare un singolo punto rosso al centro di un'immagine 512x512. (Almeno per cominciare ... Penso di poter capire il resto da lì)


1
Vedi anche stackoverflow.com/questions/902761/… sebbene quello imponesse il vincolo che PIL non poteva essere usato.
Peter Hansen,

Potresti considerare di cambiare la risposta accettata a quella di Peter ? Entrambi evita la necessità di avvolgere un oggetto attorno all'array numpy ed evita di scrivere un file temporaneo per visualizzare l'immagine.
Josiah Yoder,

Risposte:


225

È possibile utilizzare PIL per creare (e visualizzare) un'immagine:

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

3
Sembra che ci sia un bug. Si crea un array con dimensioni (w,h,3), ma dovrebbe esserlo (h,w,3), poiché l'indicizzazione in PIL differisce dall'indicizzazione in numpy. C'è domanda correlata: stackoverflow.com/questions/33725237/...
fdermishin

1
@ user502144: Grazie per aver segnalato il mio errore. Avrei dovuto creare una serie di forme (h,w,3). (Ora è riparato, sopra.) La lunghezza del primo asse può essere considerata come il numero di righe nell'array e la lunghezza del secondo asse, il numero di colonne. Quindi (h, w)corrisponde a una matrice di "altezza" he "larghezza" w. Image.fromarrayconverte questo array in un'immagine di altezza he larghezza w.
unutbu,

1
img.show()non funziona con il notebook ipython. img_pil = Image.fromarray(img, 'RGB') display(img_pil.resize((256,256), PIL.Image.LANCZOS))
MrGloom,

@unutbu questo metodo sembra immagini di distorsione ... stackoverflow.com/questions/62293077/...
Ludovico Verniani

285

Quanto segue dovrebbe funzionare:

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

Se si utilizza Jupyter notebook / lab, utilizzare questo comando inline prima di importare matplotlib:

%matplotlib inline 

3
Questo è più preciso di PIL. PIL ridimensiona / normalizza i valori dell'array, mentre pyplot utilizza i valori RGB effettivi così come sono.
GaryO,

21
Forse buono a sapersi: se si desidera visualizzare immagini in scala di grigi, è consigliabile chiamare plt.gray()una volta nel codice per passare tutti i grafici seguenti in scala di grigi. Non è ciò che l'OP vuole, ma è bene sapere comunque.
Cerno,

2
Come salvarlo?
user334639

File "<ipython-input-29-29c784f62838>", riga 39 plt.show () ^ Sintassi Errore: sintassi non valida
Mona Jalal

1
@Cerno Inoltre, le immagini in scala di grigi dovrebbero avere forma (h, w) anziché (h, w, 1). Puoi usare squeeze()per eliminare la terza dimensione:plt.imshow(data.squeeze())
Josiah Yoder,

51

Il percorso più breve è usare scipy, in questo modo:

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

Ciò richiede l'installazione di PIL o Pillow.

Un approccio simile che richiede anche PIL o Pillow ma che può invocare un visualizzatore diverso è:

from scipy.misc import imshow
imshow(data)

Quindi questo metodo non è compatibile con Python 3.5 ...?
Christopher,

@bordeo, perché sarebbe incompatibile con 3.5? È solo un'importazione e un paio di chiamate di funzione.
Peter Hansen,

PIL non è compatibile con 3.5 (non si installa)
Christopher

1
Ftr: puoi accorciarlo ulteriormente usando direttamente scipy.misc.imshow(data).
dtk

3
toimageè stato deprecato in scipy-1.0.0 e rimosso in 1.2.0, a favore di Pillow's Image.fromarray.
Sid

4

Usando pygame , puoi aprire una finestra, ottenere la superficie come una matrice di pixel e manipolarla come desideri da lì. Dovrai copiare l'array numpy nell'array di superficie, tuttavia, che sarà molto più lento rispetto alle operazioni grafiche effettive sulle stesse superfici di gioco.


3

Come mostrare le immagini memorizzate nell'array numpy con l'esempio (funziona nel notebook Jupyter)

So che ci sono risposte più semplici ma questa ti darà la comprensione di come le immagini vengono effettivamente annegate dall'array intorpidito.

Carica esempio

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

Visualizza matrice di un'immagine

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

Crea sottotrame vuote 10 x 10 per visualizzare 100 immagini

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

Tracciare 100 immagini

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

Risultato:

inserisci qui la descrizione dell'immagine

Cosa fa axes.flat? Crea un enumeratore intorpidito in modo da poter iterare sull'asse per disegnare oggetti su di essi. Esempio:

import numpy as np
x = np.arange(6).reshape(2,3)
x.flat
for item in (x.flat):
    print (item, end=' ')

2

Usando l'arancione del cuscino, ad esempio:

from PIL import Image
from numpy import *

im = array(Image.open('image.jpg'))
Image.fromarray(im).show()


0

Supplemento per farlo con matplotlib. L'ho trovato utile svolgere compiti di visione artificiale. Supponiamo che tu abbia i dati con 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))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.