user16912364
user16912364

Reputation:

Viewing a NumPy array as an image

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

Answers (2)

YoniChechik
YoniChechik

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()

EDIT

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

Lukas S
Lukas S

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

enter image description here

Upvotes: 1

Related Questions