This is what I was using for RGB .png:
from PIL import Image
import numpy
# http://www.schaik.com/pngsuite/basn2c16.png
im = Image.open('basn2c16.png')
#~ data = numpy.asarray(im)
data = numpy.array(im) # same as .asarray
print("Array dimensions: %s"%(repr(data.shape)))
data = data.astype(float)
print("[20, 30]=%s"%(repr(data[20, 30])))
print(data)
data = numpy.divide(data, 255.0)
print(data)
Nowever, note that it depends on type of .png; for instance, see http://www.schaik.com/pngsuite/pngsuite_bas_png.html for test files, and for basn2c16.png
which is "3x16 bits rgb color", the printouts are:
Array dimensions: (32, 32, 3)
[20, 30]=array([ 8., 90., 156.])
[[[ 255. 255. 0.]
[ 247. 255. 0.]
[ 239. 255. 0.]
...
[[[ 1. 1. 0. ]
[ 0.96862745 1. 0. ]
[ 0.9372549 1. 0. ]
...,
So, even if this is 16-bit, the values seem to span 0-255, as if for 8-bit. In this case, we need to scale the data with numpy.divide
with 255 to get a float range 0.0-1.0 ...
However, if you use an indexed/palleted png basn3p08.png
, you get:
Array dimensions: (32, 32)
[20, 30]=120.0
[[ 165. 165. 165. ..., 254. 254. 254.]
[ 8. 8. 8. ..., 248. 248. 248.]
....
so now the matrix contents do not represent RGB(A) values, but instead an index in a color palette, so dividing with 255 has no meaning.
Finally, if it's an RGBA png like basn6a16.png
, you will get the alpha as well:
Array dimensions: (32, 32, 4)
[20, 30]=array([ 0., 88., 167., 16.])
[[[ 255. 255. 0. 0.]
[ 247. 255. 0. 0.]
...
Again, even if this is 16-bit png, the values seem scaled to 255, so dividing with 255 to obtain floats makes sense.
In other words, its relatively easy to scale the matrix values with numpy
and PIL, however, you should make sure the matrix is in the right format for that...