2013-01-22 14 views
52

Ho appena elaborato alcune immagini utilizzando la libreria di immagini Python (PIL) usando un post che ho trovato prima per eseguire trasformazioni di Fourier di immagini e non riesco a far funzionare la funzione di salvataggio. L'intero codice funziona bene, ma appena wont salvare l'immagine risultante:Come posso salvare un'immagine con PIL?

from PIL import Image 
import numpy as np 

i = Image.open("C:/Users/User/Desktop/mesh.bmp") 
i = i.convert("L") 
a = np.asarray(i) 
b = np.abs(np.fft.rfft2(a)) 
j = Image.fromarray(b) 
j.save("C:/Users/User/Desktop/mesh_trans",".bmp") 

L'errore che ottengo è il seguente:

save_handler = SAVE[string.upper(format)] # unknown format 
    KeyError: '.BMP' 

Come posso salvare l'immagine con Pythons PIL?

risposta

67

L'errore per quanto riguarda l'estensione del file è stata gestita, si sia utilizzare bmp (senza il punto), o passaggio il nome dell'output con l'estensione già. Ora per gestire l'errore è necessario modificare correttamente i dati nel dominio della frequenza per essere salvati come immagine intera, PIL ti dice che non accetta i dati mobili da salvare come bmp.

Ecco un suggerimento (con altre modifiche minori, come l'utilizzo di fftshift e numpy.array invece di numpy.asarray) per fare la conversione per una corretta visualizzazione:

import sys 
import numpy 
from PIL import Image 

img = Image.open(sys.argv[1]).convert('L') 

im = numpy.array(img) 
fft_mag = numpy.abs(numpy.fft.fftshift(numpy.fft.fft2(im))) 

visual = numpy.log(fft_mag) 
visual = (visual - visual.min())/(visual.max() - visual.min()) 

result = Image.fromarray((visual * 255).astype(numpy.uint8)) 
result.save('out.bmp') 
+1

hey grazie mille. funziona perfettamente ora! ora tutto quello che devo fare è capire tutti i passaggi ma non sarà troppo male. grazie mille per l'aiuto – user1999274

+0

@ user1999274 la principale differenza sta nell'uso di 'fft2' invece di' rfft2' dato che per i dati discreti non vedo il punto nell'usare il dopo. Il resto è puramente cosmetico, cioè non sarebbe in grado di visualizzare correttamente la trasformata di Fourier senza applicare un fattore di registro. Quindi la normalizzazione è di mantenere le cose semplici per la conversione nell'intervallo [0, 255]. – mmgp

+0

'visual = (visual - visual.min())/(visual.max() - visual.min())' sarà predefinito se 'visual' non ha varianza (improbabile, ma vale la pena catturare) –

5

Provare a rimuovere . prima dello .bmp (non corrisponde a BMP come previsto). Come puoi vedere dall'errore, lo save_handler ha la parte superiore del format che hai fornito e quindi cerca una corrispondenza in SAVE. Tuttavia, la chiave corrispondente in quell'oggetto è BMP (anziché .BMP).

Non so molto su PIL, ma da qualche ricerca rapida intorno sembra che sia un problema con lo mode dell'immagine. Cambiare la definizione di j a:

j = Image.fromarray(b, mode='RGB') 

sembrava funzionare per me (comunque notare che ho pochissima conoscenza della PIL, quindi vorrei suggerire utilizzando la soluzione @ di MMGP come s/sa chiaramente quello che stanno facendo:)). Per i tipi di mode, ho usato la pagina this - si spera che una delle scelte funzionerà per voi.

+0

Ho provato a rimuovere il file .bmp in favore del bmp e non funzionava ancora. l'errore che ora ottengo è: IOError: impossibile scrivere la modalità F come BMP. Ho controllato le pagine del PIL per la documentazione e ha detto di usare il file .bmp, quindi nel complesso non ho ancora idea del perché non funzioni. – user1999274

+0

@ user1999274 Inserito un aggiornamento che sembrava funzionare per me (ci scusiamo per la mancanza di dettagli - unendo insieme mentre procedo :)). – RocketDonkey

+0

@RocketDonkey è un po 'più intelligente di così, perché convertire i risultati di una trasformazione di Fourier in uno spazio cromatico RGB darà un'immagine senza senso. Solo perché non solleva più un'eccezione, non significa che il risultato sia corretto. – mmgp

18

Dovreste essere in grado di lasciare semplicemente PIL ottenere il tipo di file da estensione, vale a dire l'uso:

j.save("C:/Users/User/Desktop/mesh_trans.bmp") 
+0

+1, sembra un'opzione migliore :) – RocketDonkey

+0

Grazie per l'input. tuttavia quando provo a lasciare che la funzione di salvataggio ottenga il tipo di file come suggerito sopra, ottengo il seguente errore: IOError: impossibile scrivere la modalità F come BMP. qualche consiglio? – user1999274

+0

Sì, dovresti convertire l'array in 'numpy.uint8' dtype anziché float. – wim

3

So che questo è vecchio, ma ho trovato che aprendo il file usando open(fp, 'w') e quindi il salvataggio del file funzionerà. E.g:

j.save(open(fp, 'w')) 

fp essendo il percorso del file, ovviamente. (Questo è con il cuscino)

Problemi correlati