Reputation:
I have generated a 2D NumPy array which creates polygon perimeters to look something like:
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 256 256 256 256 0 0 0
0 0 0 0 256 0 0 256 0 0 0
0 0 0 0 256 0 0 256 0 0 0
0 0 0 0 256 0 0 256 0 0 0
0 0 0 0 256 0 0 256 0 0 0
0 0 0 0 256 256 256 256 0 0 0
0 0 0 0 0 0 0 0 0 0 0
when I use:
img = Image.fromarray(array, 'L') # from PIL library
img.save('test'.png)
I expect to open the image and see a white rectangle outline in an otherwise black backdrop but instead I get weird pseudorandom lines. I have tried replacing all the zeros with 1s and this simply changes the image to 3 straight vertical lines.
Any thoughts on what I am doing wrong?
Upvotes: 1
Views: 3084
Reputation: 1537
Your problem is that uint8 (what used with PIL in this case) is up to 255 (not 256). This code produces a correct result:
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
im_arr = np.array(
[[0, 0, 0, 0, 0 , 0 , 0 , 0 , 0, 0 ,0],
[0, 0, 0, 0, 255, 255, 255, 255, 0, 0 ,0],
[0, 0, 0, 0, 255, 0 , 0 , 255, 0, 0 ,0],
[0, 0, 0, 0, 255, 0 , 0 , 255, 0, 0 ,0],
[0, 0, 0, 0, 255, 0 , 0 , 255, 0, 0 ,0],
[0, 0, 0, 0, 255, 0 , 0 , 255, 0, 0 ,0],
[0, 0, 0, 0, 255, 255, 255, 255, 0, 0 ,0],
[0, 0, 0, 0, 0 , 0 , 0 , 0 , 0, 0 ,0]])
im = Image.fromarray(np.uint8(im_arr))
plt.imshow(im)
plt.show()
HI @AdamBrooks, numpy infers the list given as input according to the list's object types. for example:
>>> import numpy as np
>>> a=np.array([1,2,3])
>>> a
array([1, 2, 3])
>>> a.dtype
dtype('int64')
>>> b=np.array([1,2,3.5])
>>> b.dtype
dtype('float64')
You need to convert the input type to np.uint8 if you wish to use them as an image in your case.
Upvotes: 2
Reputation: 3603
Fortunately matplotlib
has a special function called matshow
exactly for your use case.
import numpy as np
import matplotlib.pyplot as plt
arr = np.array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 256, 256, 256, 256, 0, 0, 0],
[ 0, 0, 0, 0, 256, 0, 0, 256, 0, 0, 0],
[ 0, 0, 0, 0, 256, 0, 0, 256, 0, 0, 0],
[ 0, 0, 0, 0, 256, 0, 0, 256, 0, 0, 0],
[ 0, 0, 0, 0, 256, 0, 0, 256, 0, 0, 0],
[ 0, 0, 0, 0, 256, 256, 256, 256, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
plt.matshow(arr, cmap='gray')
Upvotes: 1