2013-01-22 14 views
52

Właśnie zrobiłem przetwarzanie obrazów za pomocą biblioteki obrazów Python (PIL) za pomocą posta, który znalazłem wcześniej, aby wykonać fourierowe transformacje obrazów i nie mogę uruchomić funkcji zapisu. Cały kod działa poprawnie, ale po prostu przyzwyczajenie zapisać obraz wynikowy:Jak mogę zapisać obraz z 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") 

Błąd pojawia się następująco:

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

Jak mogę zapisać obraz z pytony PIL?

Odpowiedz

67

Błąd dotyczące rozszerzenia pliku zostały przeładowane, możesz albo użyć bmp (bez kropki) lub karnet nazwa wyjściowa z rozszerzeniem już. Teraz, aby poradzić sobie z błędem, musisz odpowiednio zmodyfikować dane w dziedzinie częstotliwości, aby zapisać je jako obraz całkowity, PIL mówi, że nie akceptuje danych pływowych do zapisania jako bmp.

Oto propozycja (wraz z innymi niewielkimi modyfikacjami, jak przy użyciu fftshift i numpy.array zamiast numpy.asarray) do wykonywania konwersji do prawidłowej wizualizacji:

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

hej dziękuję bardzo. teraz działa idealnie! teraz wszystko, co muszę zrobić, to zrozumieć wszystkie kroki, ale to nie będzie zbyt złe. dziękuję bardzo za pomoc – user1999274

+0

@ user1999274 główną różnicą jest użycie 'fft2' zamiast' rfft2' ponieważ dla dyskretnych danych nie widzę sensu korzystania z późniejszego. Reszta jest czysto kosmetyczna, tzn. Nie można poprawnie wizualizować transformaty Fouriera bez stosowania współczynnika logu do niej. Następnie normalizacja polega na utrzymaniu prostoty konwersji do zakresu [0, 255]. – mmgp

+0

'visual = (visual - visual.min())/(visual.max() - visual.min())' będzie domyślne, jeśli 'visual' nie będzie miał wariancji (mało prawdopodobne, ale warte zachwycenia) –

5

Spróbuj usunąć . przed .bmp (zgodnie z oczekiwaniami nie jest to zgodne z BMP). Jak widać z błędu, save_handler jest górną obudową dostarczonego format, a następnie szukając dopasowania w SAVE. Jednak odpowiedni klucz w tym obiekcie to BMP (zamiast .BMP).

Niewiele wiem o PIL, ale z szybkiego wyszukiwania wydaje mi się, że jest to problem z obrazem mode. Zmiana definicji j do:

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

wydawało się działać dla mnie (jednak pamiętać, że mają bardzo małą wiedzę PIL, więc chciałbym zaproponować za pomocą roztworu @ mmgp jako on/ona wyraźnie wie, co robią:)). Dla typów mode użyłem strony this - mam nadzieję, że jeden z wyborów tam będzie działał.

+0

Próbowałem usunąć. Bmp na rzecz bmp i nadal nie działa. błąd, który teraz otrzymuję, to: IOError: nie można zapisać trybu F jako BMP. Sprawdziłem strony PIL dla dokumentacji i powiedział, żebym użył .bmp, więc ogólnie nie mam pojęcia, dlaczego to nie działa. – user1999274

+0

@ user1999274 Wysłałem aktualizację, która wydawała się działać dla mnie (przepraszam za brak szczegółów - składając ją razem, gdy idę :)). – RocketDonkey

+0

@RocketDonkey jest trochę mądrzejszy, ponieważ przekształcenie wyników transformaty Fouriera w przestrzeń kolorów RGB da bezsensowny obraz. Tylko dlatego, że nie podnosi już wyjątku, nie oznacza to, że wynik jest poprawny. – mmgp

18

Powinieneś być w stanie po prostu niech PIL uzyskać typ pliku z rozszerzeniem, czyli zastosowanie:

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

+1, wydaje się lepszym rozwiązaniem :) – RocketDonkey

+0

Dzięki za wejście. jednak gdy próbuję pozwolić funkcji zapisu uzyskać typ pliku, jak sugerujesz powyżej, otrzymuję następujący błąd: IOError: nie można zapisać trybu F jako BMP. jakakolwiek rada? – user1999274

+0

Tak, powinieneś przekonwertować tablicę na 'numpy.uint8' dtype zamiast na float. – wim

3

wiem, że to jest stary, ale znalazłem otwarcie pliku przy użyciu open(fp, 'w'), a następnie zapisanie pliku, będzie działało. Np .:

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

fp ścieżką do pliku, oczywiście. (To jest z Pillow)