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?
CodePudding user response:
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()
CodePudding user response:
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')