Getting List of Pixel Values from Pil

Getting pixels from an image using PIL

You can read pixels with Image.getpixel() from PIL.

The code below will give you all non-white pixels in the form of a 2D list.

from PIL import Image

im = Image.open('x.bmp')

imageSizeW, imageSizeH = im.size

nonWhitePixels = []

for i in range(1, imageSizeW):
for j in range(1, imageSizeH):
pixVal = im.getpixel((i, j))
if pixVal != (255, 255, 255):
nonWhitePixels.append([i, j])

print(nonWhitePixels)

Get pixel's RGB using PIL

Yes, this way:

im = Image.open('image.gif')
rgb_im = im.convert('RGB')
r, g, b = rgb_im.getpixel((1, 1))

print(r, g, b)
(65, 100, 137)

The reason you were getting a single value before with pix[1, 1] is because GIF pixels refer to one of the 256 values in the GIF color palette.

See also this SO post: Python and PIL pixel values different for GIF and JPEG and this PIL Reference page contains more information on the convert() function.

By the way, your code would work just fine for .jpg images.

How to create image from a list of pixel values in Python3?

PIL and numpy are your friends here:

from PIL import Image
import numpy as np

pixels = [
[(54, 54, 54), (232, 23, 93), (71, 71, 71), (168, 167, 167)],
[(204, 82, 122), (54, 54, 54), (168, 167, 167), (232, 23, 93)],
[(71, 71, 71), (168, 167, 167), (54, 54, 54), (204, 82, 122)],
[(168, 167, 167), (204, 82, 122), (232, 23, 93), (54, 54, 54)]
]

# Convert the pixels into an array using numpy
array = np.array(pixels, dtype=np.uint8)

# Use PIL to create an image from the new array of pixels
new_image = Image.fromarray(array)
new_image.save('new.png')

EDIT:

A little fun with numpy to make an image of random pixels:

from PIL import Image
import numpy as np

def random_img(output, width, height):

array = np.random.random_integers(0,255, (height,width,3))

array = np.array(array, dtype=np.uint8)
img = Image.fromarray(array)
img.save(output)

random_img('random.png', 100, 50)

How to read the RGB value of a given pixel in Python?

It's probably best to use the Python Image Library to do this which I'm afraid is a separate download.

The easiest way to do what you want is via the load() method on the Image object which returns a pixel access object which you can manipulate like an array:

from PIL import Image

im = Image.open('dead_parrot.jpg') # Can be many different formats.
pix = im.load()
print im.size # Get the width and hight of the image for iterating over
print pix[x,y] # Get the RGBA Value of the a pixel of an image
pix[x,y] = value # Set the RGBA Value of the image (tuple)
im.save('alive_parrot.png') # Save the modified pixels as .png

Alternatively, look at ImageDraw which gives a much richer API for creating images.

How to get a list of float RGBA pixels values using Pillow?

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



Related Topics



Leave a reply



Submit