2013-01-22 19 views
52

Ich habe gerade einige Bildverarbeitung mit der Python-Image-Bibliothek (PIL) mit einem Beitrag ich früher gefunden, um Fourier-Transformationen von Bildern durchzuführen und ich kann nicht die Speicherfunktion funktionieren. Der gesamte Code funktioniert gut, aber es spart einfach gewohnt das resultierende Bild:Wie kann ich ein Bild mit PIL speichern?

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

Der Fehler ich erhalte, ist die folgende:

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

Wie kann ich ein Bild mit Pythons PIL retten?

Antwort

67

Der Fehler in Bezug auf die Dateierweiterung behandelt wurde, entweder Sie bmp verwenden (ohne Punkt) oder Pass der Ausgabename mit der Erweiterung bereits. Um nun den Fehler zu behandeln, den Sie brauchen, um Ihre Daten in der Frequenzdomäne richtig zu ändern, um als Integer-Bild gespeichert zu werden, teilt Ihnen PIL mit, dass Float-Daten nicht akzeptiert werden, um sie als BMP zu speichern. Hier

ist ein Vorschlag (mit anderen geringfügigen Modifikationen, wie mit fftshift und numpy.array statt numpy.asarray) für das Erledigen der Umwandlung für die richtige Visualisierung:

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 vielen dank. es funktioniert jetzt perfekt! Jetzt muss ich nur noch alle Schritte verstehen, aber das wird nicht zu schlecht sein. Vielen Dank für die Hilfe – user1999274

+0

@ user1999274 der Hauptunterschied ist in der Verwendung von 'fft2' statt' rfft2', da für diskrete Daten ich nicht den Punkt in der Verwendung der später sehe. Der Rest ist rein kosmetischer Natur, d. H. Sie wären nicht in der Lage, die Fourier-Transformation richtig darzustellen, ohne einen logarithmischen Faktor darauf anzuwenden. Dann ist die Normalisierung, um die Dinge für die Umwandlung in den Bereich [0, 255] einfach zu halten. – mmgp

+0

'visual = (visual - visual.min())/(visual.max() - visual.min())' wird als Standard verwendet, wenn 'visual' keine Varianz hat (unwahrscheinlich, aber es lohnt sich) –

5

Versuchen Sie, die . vor der .bmp zu entfernen (es entspricht nicht BMP wie erwartet). Wie Sie aus dem Fehler sehen können, ist die save_handler oberen Gehäuse die format Sie zur Verfügung gestellt und dann auf der Suche nach einer Übereinstimmung in SAVE. Der entsprechende Schlüssel in diesem Objekt ist jedoch BMP (anstelle von .BMP).

Ich weiß nicht viel über PIL, aber von einigen schnellen Suche scheint es, dass es ein Problem mit der mode des Bildes ist. Änderung der Definition von j zu:

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

Schien für mich zu arbeiten (aber beachten Sie, dass ich sehr wenig Wissen über PIL haben, so würde ich vorschlagen, @ MMgP-Lösung als s mit/er weiß genau, was sie tun:)). Für die Typen von mode habe ich this Seite verwendet - hoffentlich wird eine der Möglichkeiten dort für Sie arbeiten.

+0

Ich habe versucht, die. BMP zugunsten der BMP und die es immer noch nicht funktioniert. Der Fehler, den ich jetzt bekomme, ist: IOError: kann den Modus F nicht als BMP schreiben. Ich überprüfte die PIL-Seiten für Dokumentation und sagte, dass ich die .bmp verwenden sollte, also habe ich immer noch keine Ahnung, warum es nicht funktioniert. – user1999274

+0

@ user1999274 Posted ein Update, das schien für mich zu arbeiten (Entschuldigung für den Mangel an Details - zusammenfügen, wie ich zusammen gehe :)). – RocketDonkey

+0

@ RocketDonkey es ist ein wenig schlauer als das, weil die Umwandlung der Ergebnisse einer Fourier-Transformation in einen RGB-Farbraum ein bedeutungsloses Bild ergibt. Nur weil es keine Ausnahme mehr gibt, bedeutet das nicht, dass das Ergebnis korrekt ist. – mmgp

18

sollten Sie in der Lage sein, einfach PIL den Dateityp von der Verlängerung erhalten zu lassen, dh Nutzung:

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

+1, scheint eine bessere Option :) – RocketDonkey

+0

Danke für die Eingabe. Wenn ich jedoch versuche, die Speicherfunktion den Dateityp wie oben vorgeschlagen erhalten zu lassen, erhalte ich den folgenden Fehler: IOError: kann den Modus F nicht als BMP schreiben. irgendein Rat? – user1999274

+0

Ja, Sie sollten das Array in 'numpy.uint8' dtype anstatt float konvertieren. – wim

3

Ich weiß, dass diese alten, aber ich habe festgestellt, dass das Öffnen der Datei mit open(fp, 'w') und dann das Speichern der Datei funktioniert. Z. B:

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

fp der Dateipfad sein, natürlich. (Dies ist mit Kissen)

Verwandte Themen