50

Ho un problema semplice ma non riesco a trovare una buona soluzione.Come convertire l'array Numpy in immagine PIL applicando la mappa colori matplotlib

Voglio prendere una matrice 2D numpy che rappresenta un'immagine in scala di grigi e convertirla in un'immagine RGB PIL mentre si applicano alcune delle mappe dei colori Matplotlib.

posso ottenere un'uscita PNG ragionevole utilizzando il comando pyplot.figure.figimage:

dpi = 100.0 
w, h = myarray.shape[1]/dpi, myarray.shape[0]/dpi 
fig = plt.figure(figsize=(w,h), dpi=dpi) 
fig.figimage(sub, cmap=cm.gist_earth) 
plt.savefig('out.png') 

Anche se ho potuto adattare questo per ottenere ciò che voglio (probabilmente usando StringIO si ottiene l'immagine PIL), mi chiedo se c'è non è un modo più semplice per farlo, dal momento che sembra essere un problema molto naturale di visualizzazione delle immagini. Diciamo, qualcosa del genere:

colored_PIL_image = magic_function(array, cmap) 

Grazie per la lettura!

+0

Per codice pienamente funzionante, puoi ref: [Esiste una buona mappa dei colori per convertire l'immagine in scala di grigi in quelli colorati usando python's PIL?] (Http://stackoverflow.com/questions/43457308/is-there-any- good-color-map-to-convert-gray-scale-image-to-colourful-ones-using-p) – Adam

risposta

99

Piuttosto un occupato uno di linea, ma qui è:

  1. Primo garantire l'array NumPy, myarray, è normalizzata con il valore massimo a 1.0.
  2. Applica la mappa dei colori direttamente a myarray.
  3. Rescale fino alla gamma 0-255.
  4. Convertire in numeri interi, utilizzando np.uint8().
  5. Utilizzare Image.fromarray().

E il gioco è fatto:

from PIL import Image 
im = Image.fromarray(np.uint8(cm.gist_earth(myarray)*255)) 

con plt.savefig():

enter image description here

con im.save():

enter image description here

+4

Il "Applica la mappa di colori direttamente a' myarray' "parte tagliata direttamente al cuore! Non sapevo che fosse possibile, grazie! – heltonbiker

+0

@heltonbiker - sì, è piuttosto bello;) – fraxel

+27

Studiando i documenti su LinearSegmentedColormap (da cui cm.gist_earth è un'istanza), ho scoperto che è possibile chiamarlo con un argomento "bytes" che lo converte già in uint8. Quindi, la one-liner diventa molto più tranquilla: 'im = Image.fromarray (cm.gist_earth (myarray, byte = True))' – heltonbiker

Problemi correlati