2

I want to get a list of float RGBA pixels values using Pillow python module.

So far I could only get the RGBA integer data:

from PIL import Image

im = Image.open("Lenna.png")
im_alpha = im.convert('RGBA')
Pixels = list(im.getdata())

This will get me for instance ((226, 137, 125, 255), ...) However I don't know how to get this information in a form of floating points, for instance ((0.88627451, 0.537254902, 0.490196078, 1), ...).

How can I do that?

  • 1
    http://stackoverflow.com/questions/2262100/rgb-int-to-rgb-python – PeteyPii Nov 25 '16 at 18:37
  • 1
    @PeteyPii How does this help me? I want the pixel info to be in the form (0.1454,0.4572,1,1), And of course I can just normalize it, but I am looking for a better way to do it using Pillow itself. –  Nov 25 '16 at 18:44
  • Oh, I misinterpreted your question. You should clarify exactly what you mean in the question. – PeteyPii Nov 25 '16 at 18:52
  • I don't think PIL stores pixel values in float. Because even if you did manage to convert your image to `type float`, you will get the pixel values as : `255.0, 35.0, 168.0, 87.0,.....` and so on. – Jeru Luke Jan 05 '17 at 16:24

1 Answers1

1

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...

sdaau
  • 36,975
  • 46
  • 198
  • 278