I think the answer is wrong. The Image.fromarray( ____ , 'L') function seems to only work properly with an array of integers between 0 and 255. I use the np.uint8 function for this.
You can see this demonstrated if you try to make a gradient.
import numpy as np
from PIL import Image
# gradient between 0 and 1 for 256*256
array = np.linspace(0,1,256*256)
# reshape to 2d
mat = np.reshape(array,(256,256))
# Creates PIL image
img = Image.fromarray(np.uint8(mat * 255) , 'L')
img.show()
Makes a clean gradient
vs
import numpy as np
from PIL import Image
# gradient between 0 and 1 for 256*256
array = np.linspace(0,1,256*256)
# reshape to 2d
mat = np.reshape(array,(256,256))
# Creates PIL image
img = Image.fromarray( mat , 'L')
img.show()
Has the same kind of artifacting.
Answer from Nathan on Stack OverflowI think the answer is wrong. The Image.fromarray( ____ , 'L') function seems to only work properly with an array of integers between 0 and 255. I use the np.uint8 function for this.
You can see this demonstrated if you try to make a gradient.
import numpy as np
from PIL import Image
# gradient between 0 and 1 for 256*256
array = np.linspace(0,1,256*256)
# reshape to 2d
mat = np.reshape(array,(256,256))
# Creates PIL image
img = Image.fromarray(np.uint8(mat * 255) , 'L')
img.show()
Makes a clean gradient
vs
import numpy as np
from PIL import Image
# gradient between 0 and 1 for 256*256
array = np.linspace(0,1,256*256)
# reshape to 2d
mat = np.reshape(array,(256,256))
# Creates PIL image
img = Image.fromarray( mat , 'L')
img.show()
Has the same kind of artifacting.
If I understood you question, you want to get a grayscale image using PIL.
If this is the case, you do not need to multiply each pixels by 255.
The following worked for me
import numpy as np
from PIL import Image
# Creates a random image 100*100 pixels
mat = np.random.random((100,100))
# Creates PIL image
img = Image.fromarray(mat, 'L')
img.show()
python - Use PIL to convert a grayscale image to a (1, H, W) numpy array - Stack Overflow
python - Grayscale image to NumPy array for Fourier transform - Stack Overflow
image - Read the picture as a grayscale numpy array, and save it back - Stack Overflow
Grayscale images (as numpy arrays) display as blue for values of exactly -1?
How do I convert a PIL image to a NumPy array?
How do I convert a NumPy array back to a PIL image?
What is the difference between np.asarray() and np.array()?
You want to use the mode 'L' instead of 'LA' as the parameter to the convert() method. 'LA' leaves an alpha channel and then the numpy.asarray doesn't work as you intended. If you need the alpha channel, then you will need a different method to convert to a numpy array. Otherwise, use mode 'L'.
It looks like you're using a version of PIL prior to 1.1.6, where they introduced the methods so that numpy would know what to do with an Image. So you're just getting img_as_np as a one-element array containing an Image object (which is what Out[4] is showing you).
You instead need to do something like np.asarray(img.getdata()), which will give you a num_pixels x num_channels array of integers between 0 and 255 (at least for the png I tried). You may want to do
img_as_np = np.asarray(img.getdata()).reshape(img.size[1], img.size[0], -1)
to lay it out like the image (transposed). You might also want to divide by 255 to get float values between 0 and 1, if that's the format you're expecting (as does e.g. matplotlib's imshow).