PIL ile bir görüntüyü nasıl kaydedebilirim?


119

Az önce Python görüntü kitaplığını (PIL) kullanarak daha önce bulduğum bir gönderiyi kullanarak görüntülerin fourier dönüşümlerini gerçekleştirdim ve kaydetme işlevini çalıştıramıyorum. Kodun tamamı iyi çalışıyor ancak ortaya çıkan görüntüyü kaydetmeyecek:

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

Aldığım hata şu:

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

Pythons PIL ile bir görüntüyü nasıl kaydedebilirim?

Yanıtlar:


144

Dosya uzantısıyla ilgili hata işlendi, ya kullanırsınız BMP(nokta olmadan) veya zaten uzantı ile çıktı adını iletirsiniz. Şimdi hatayı gidermek için, frekans alanındaki verilerinizi tamsayı görüntüsü olarak kaydedilecek doğru şekilde değiştirmeniz gerekiyor, PILsize BMP olarak kaydetmek için kayan verileri kabul etmediğini söylüyor.

Doğru görselleştirme için dönüştürme yapmak için bir öneri (kullanmak fftshiftve numpy.arrayyerine kullanmak gibi diğer küçük değişikliklerle birlikte numpy.asarray):

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 çok teşekkürler. şimdi mükemmel çalışıyor! şimdi tek yapmam gereken tüm adımları anlamak ama bu çok kötü olmayacak. yardım için çok teşekkür ederim
user1999274

@ user1999274 en büyük fark, ayrık veriler için daha sonrasını kullanmanın anlamını görmüyorum çünkü fft2yerine kullanımında olmasıdır rfft2. Geri kalanı tamamen kozmetiktir, yani Fourier dönüşümünü ona bir günlük faktörü uygulamadan doğru şekilde görselleştiremezsiniz. Daha sonra normalleştirme, [0, 255] aralığına dönüşüm için işleri basit tutmaktır.
mmgp

1
visual = (visual - visual.min()) / (visual.max() - visual.min())visualhiçbir varyansı yoksa varsayılan olacaktır (olası değildir, ancak yakalanmaya değer)

1
Sorunum için bu kodu kullanmayı denedim, ancak düz siyah görüntüler alıyorum. Bunun hakkında bir fikri olan var mı? stackoverflow.com/questions/24266000/…
user961627

32

PIL'in dosya türünü uzantıdan almasına izin verebilmelisiniz, yani şunu kullanın:

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

1
Giriş için teşekkürler. ancak kaydetme işlevinin yukarıda önerdiğiniz gibi dosya türünü almasına izin vermeye çalıştığımda şu hatayı alıyorum: IOError: F modunu BMP olarak yazamıyorum. herhangi bir tavsiye?
user1999274

1
Evet, diziyi numpy.uint8float yerine dtype'a dönüştürmelisiniz .
2013

6

Kaldırmayı deneyin .önce .bmp(o eşleştirme değil BMPbeklendiği gibi). Hatadan da görebileceğiniz gibi, sağladığınız save_handlerüst kasa formatve ardından bir eşleşme aranıyor SAVE. Ancak bu nesnede karşılık gelen anahtar BMP(yerine .BMP).

Hakkında pek bir şey bilmiyorum PIL, ancak etrafta yapılan bazı hızlı araştırmalardan mode, görüntüyle ilgili bir sorun olduğu anlaşılıyor . Tanımını şu şekilde değiştirme j:

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

Benim için işe yarıyor gibi görünüyordu (ancak çok az bilgim olduğuna dikkat edin PIL, bu yüzden ne yaptıklarını açıkça bildiği için @ mmgp çözümünü kullanmanızı öneririm :)). Türleri için bu sayfayı modekullandım - umarım oradaki seçeneklerden biri sizin için işe yarar.


.Bmp'yi bmp lehine kaldırmayı denedim ve hala işe yaramadı. şimdi aldığım hata: IOError: BMP olarak F modu yazılamıyor. Dokümantasyon için PIL sayfalarını kontrol ettim ve .bmp'yi kullanmamı söyledi, bu yüzden genel olarak neden çalışmadığı konusunda hala bir fikrim yok.
user1999274

@ user1999274 Benim için işe yarayan bir güncelleme yayınladı (ayrıntı eksikliği için özür dilerim - ilerledikçe bir araya getirerek :)).
RocketDonkey

@RocketDonkey bundan biraz daha akıllı çünkü bir Fourier dönüşümünün sonuçlarını RGB renk uzayına dönüştürmek anlamsız bir görüntü verecektir. Artık bir istisna oluşturmadığı için, sonucun doğru olduğu anlamına gelmez.
mmgp

@mmgp Kabul Edildi - bu yüzden seninkini +
1'ledim

4

Bunun eski olduğunu biliyorum, ancak (Pillow kullanırken) dosyayı kullanarak açıp open(fp, 'w')daha sonra dosyayı kaydetmenin işe yarayacağını buldum . Örneğin:

with open(fp, 'w') as f:
    result.save(f)

fp tabii ki dosya yolu.


1
Pillow'un dokümantasyonu , formatbir dosya nesnesi kullanıldığında parametrenin kullanılması gerektiğini söylüyor save. Bu gerekli değil mi?
Rob Gül

@RobRose, testlerim sırasında cevabı gönderirken, gerekli olacak böyle bir şey bulamadım. Ancak, şimdi durum böyle olabilir. Yaptığınız herhangi bir testin gerekli olduğunu kanıtlarsanız bana bildirin ve cevabımı düzenleyeceğim
necko
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.