1. ホーム
  2. python

[解決済み] Image.fromarrayは黒い画像を生成するだけです。

2022-01-28 15:58:30

質問

numpy の行列をグレースケール画像として保存するには、次のようにします。 Image.fromarray . ランダムな行列ではうまくいくようですが、特定の行列(円が表示されるはずの場所)ではうまくいきません。誰か私が間違っていることを説明できますか?

from PIL import Image
import numpy as np
radius = 0.5
size = 10
x,y = np.meshgrid(np.linspace(-1,1,size),np.linspace(-1,1,size))
f = np.vectorize(lambda x,y: ( 1.0 if x*x + y*y < radius*radius else 0.0))
z = f(x,y)
print(z)
zz = np.random.random((size,size))
img = Image.fromarray(zz,mode='L') #replace z with zz and it will just produce a black image
img.save('my_pic.png')

解決方法は?

Image.fromarray は浮動小数点数の入力に対してうまく定義されていません。よく文書化されていませんが、この関数は入力が符号なし8ビット整数としてレイアウトされていると仮定しています。

得ようとする出力を得るには、255を掛けて、次のように変換します。 uint8 :

z = (z * 255).astype(np.uint8)

ランダムな配列で動作しているように見えるのは、この配列のバイトを符号なし8ビット整数として解釈すると、これもランダムに見えるからです。しかし、出力は入力と同じランダム配列ではありません。これは、ランダム入力に対して上記の変換を行うことで確認することができます。

np.random.seed(0)
zz = np.random.rand(size, size)
Image.fromarray(zz, mode='L').save('pic1.png')

Image.fromarray((zz * 255).astype('uint8'), mode='L').save('pic2.png')

この問題はどこにも報告されていないようなので、githubで報告しました。 https://github.com/python-pillow/Pillow/issues/2856