web-dev-qa-db-fra.com

Image.fromarray produit juste une image noire

J'essaie d'enregistrer une matrice numpy en tant qu'image en niveaux de gris à l'aide de Image.fromarray. Il semble fonctionner sur une matrice aléatoire, mais pas sur une matrice particulière (où devrait apparaître un cercle). Quelqu'un peut-il expliquer ce que je fais mal?

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')
18
flawr

Image.fromarray est mal défini avec une entrée en virgule flottante; ce n'est pas bien documenté, mais la fonction suppose que l'entrée est présentée sous forme d'entiers 8 bits non signés.

Pour produire la sortie que vous essayez d'obtenir, multipliez par 255 et convertissez en uint8:

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

La raison pour laquelle il semble fonctionner avec le tableau aléatoire est que les octets de ce tableau, lorsqu'ils sont interprétés comme des entiers 8 bits non signés, semblent également aléatoires. Mais la sortie n'est pas le même tableau aléatoire que l'entrée, que vous pouvez vérifier en effectuant la conversion ci-dessus sur l'entrée aléatoire:

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

pic1.png

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

pic2.png

Étant donné que le problème ne semble être signalé nulle part, je l'ai signalé sur github: https://github.com/python-pillow/Pillow/issues/2856

25
jakevdp