PILで画像を保存するにはどうすればよいですか?


118

前に見つけた投稿を使用して画像のフーリエ変換を実行するために、Python画像ライブラリ(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")

私が得るエラーは次のとおりです:

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

Python PILで画像を保存するにはどうすればよいですか?

回答:


143

ファイル拡張子に関するエラーが処理されました。BMP(ドットなしで)使用するか、出力名を拡張子付きで渡します。エラーを処理するにPILは、整数画像として保存されるように周波数領域のデータを適切に変更する必要がありますが、BMPとして保存するための浮動小数点データを受け入れないことを通知しています。

ここで(使用してのような他のマイナーな修正と、提案されfftshiftそしてnumpy.array代わりに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
どうもありがとう。それは今完璧に動作します!今私がしなければならないすべてはすべてのステップを理解することですが、それは悪くないでしょう。ヘルプありがとうございました
user1999274

@ user1999274主な違いは、の使用にありfft2ます。rfft2離散データの場合、後者を使用する意味がわかりません。残りは純粋に表面的なものです。つまり、フーリエ変換にログファクターを適用せずに適切に視覚化することはできません。次に、正規化は、範囲[0、255]への変換のために物事を単純に保つことです。
mmgp 2013年

1
visual = (visual - visual.min()) / (visual.max() - visual.min())visual差異がない場合はデフォルトになります(可能性は低いですが、キャッチする価値があります)

1
問題に対してこのコードを使用しようとしましたが、真っ黒な画像が表示されました。誰かこれについて何か考えがありますか?stackoverflow.com/questions/24266000/...
user961627

32

あなたは単にPILに拡張子からファイルタイプを取得させることができるはずです、すなわち使用します:

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

1
入力いただきありがとうございます。ただし、上記で提案したようなファイルタイプを保存関数に取得させようとすると、次のエラーが発生します。IOError:モードFをBMPとして書き込むことができません。何かアドバイス?
user1999274 2013年

1
はい、配列をnumpy.uint8浮動小数点数ではなくdtypeに変換する必要があります。
2013年

6

.前のを削除してみてください.bmpBMP期待どおりに一致しません)。エラーからわかるように、save_handlerは指定したを大文字にformatして、で一致を探しますSAVE。ただし、そのオブジェクトの対応するキーはBMP(ではなく.BMP)です。

についてはよくわかりませんが、PIL簡単に調べてみるmodeと、画像のに問題があるようです。の定義を次のjように変更します。

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

私のために働くPILように見えました(ただし、私はについてほとんど知識がないので、@ mmgpのソリューションを使用することをお勧めします。のタイプについてはmodeこのページを使用しました -うまくいけば、そこにある選択肢の1つが役立つでしょう。


bmpを優先して.bmpを削除しようとしましたが、それでも機能しません。私が今得るエラーは:IOError:モードFをBMPとして書き込むことができません。ドキュメントのPILページを確認したところ、.bmpを使用するように言われたので、全体的になぜそれが機能しないのかわかりません。
user1999274 2013年

@ user1999274自分に効果があるように思われる更新を投稿しました(詳細の欠如に対する謝罪-私が進むにつれてそれをつなぎ合わせます:))。
RocketDonkey 2013年

@RocketDonkeyでは、フーリエ変換の結果をRGB色空間に変換すると意味のない画像が得られるため、それよりも少し賢くなっています。例外が発生しなくなったからといって、結果が正しいとは限りません。
mmgp 2013年

@mmgp同意-それが私が+1してOPがそれを受け入れることを望んでいる理由です:)
RocketDonkey

4

これは古いことはわかっていますが、(Pillowを使用しているときに)を使用してファイルを開き、ファイルをopen(fp, 'w')保存すると機能することがわかりました。例えば:

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

fp もちろんファイルパスです。


1
Pillowのドキュメントにformat、ファイルオブジェクトがで使用されてsaveいる場合、パラメーターを使用する必要があると記載されています。これは必要ありませんか?
ロブ・ローズ

テスト中に@RobRoseを使用して回答を投稿したところ、そのようなものは必要であることがわかりませんでした。しかし、それは今のケースかもしれません。あなたがいずれかのテストが判明した場合には、必要に応じて私が知っていると私は私の答えを編集します
のnecko
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.