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 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.
Is there a way to get an RGB value of a pixel on a frame of a GIF in PIL?
Try
r, g, b, a = img.getpixel((x, y))
I tested this and it works for me. Based on [this post].
(Get pixel's RGB using PIL)
Edit: another approach that has worked for me in the past is to use pixels = img.load()
and index a pixel like pixels[x, y]
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)
How to Access and Change Color Channels using PIL?
If, for example, you want to multiply all pixels in the red channel by 1.2, and all the green pixels by 0.9, you have several options....
Split the image into Red, Green and Blue channels, upscale the Red channel and recombine:
from PIL import Image
im = Image.open('image.jpg').convert('RGB')
# Split into 3 channels
r, g, b = im.split()
# Increase Reds
r = r.point(lambda i: i * 1.2)
# Decrease Greens
g = g.point(lambda i: i * 0.9)
# Recombine back to RGB image
result = Image.merge('RGB', (r, g, b))
result.save('result.png')
See "Processing Individual Bands" here.
Or, use a matrix to transform the channels:
from PIL import Image
# Open image
im = Image.open('image.jpg')
# Make transform matrix, to multiply R by 1.1, G by 0.9 and leave B unchanged
# newRed = 1.1*oldRed + 0*oldGreen + 0*oldBlue + constant
# newGreen = 0*oldRed + 0.9*OldGreen + 0*OldBlue + constant
# newBlue = 0*oldRed + 0*OldGreen + 1*OldBlue + constant
Matrix = ( 1.1, 0, 0, 0,
0, 0.9, 0, 0,
0, 0, 1, 0)
# Apply transform and save
im = im.convert("RGB", Matrix)
im.save('result.png')
Or, convert to Numpy array, do some processing and convert back to PIL Image:
from PIL import Image
# Open image
im = Image.open('image.jpg')
# Make into Numpy array of floats
na = np.array(im).astype(np.float)
# Multiply all red values by 1.1
na[...,0] *= 1.1
# Reduce green values
na[...,1] *= 0.9
# You may want to use "np.clip()" here to ensure you don't exceed 255
# Convert Numpy array back to PIL Image and save
pi = Image.fromarray(na.astype(np.uint8))
pi.save('result.png')
This option has the added benefit that the Numpy arrays can be intermixed and processed with OpenCV, scikit-image, vips, wand and other libraries to get MUCH more sophisticated processing done - morphology, granulometry, video processing, SIFT, object tracking...
Pillow - Change every pixel's RGB value
JPEG is a lossy compression format, which means you should not expect to retrieve the exact same pixel values you saved. If you want exact values, you should probably try PNG.
PIL? Extract all pixels of a given RGB value
Here is a pixelwise way of doing it, which can work for any number of colors in the image (although it can get slow for many colours and large images). It also will work for paletted images (it converts them).
import Image
def color_separator(im):
if im.getpalette():
im = im.convert('RGB')
colors = im.getcolors()
width, height = im.size
colors_dict = dict((val[1],Image.new('RGB', (width, height), (0,0,0)))
for val in colors)
pix = im.load()
for i in xrange(width):
for j in xrange(height):
colors_dict[pix[i,j]].putpixel((i,j), pix[i,j])
return colors_dict
im = Image.open("colorwheel.tiff")
colors_dict = color_separator(im)
#show the images:
colors_dict.popitem()[1].show()
colors_dict.popitem()[1].show()
- Calling
im.getcolors()
returns a list of all the colors in the image and the number of times they occur, as a tuple, unless the number of colors exceeds a max value (which you can specify, and defaults to 256). - We then build a dictionary
colors_dict
, keyed by the colors in the image, and with corresponding values of empty images. - We then iterate over the image for all pixels, updating the appropriate dictionary entry for each pixel. Doing it like this means we only need to read through the image once. We use
load()
to make pixel access faster as we read through the image. color_separator()
returns a dictionary of images, keyed by every unique colour in the image.
To make it faster you could use load()
for every image in colors_dict
, but you may need to be a little careful as it could consume a lot of memory if the images have many colours and are large. If this isn't an issue then add (after the creation of colors_dict
):
fast_colors = dict((key, value.load()) for key, value in colors_dict.items())
and swap:
colors_dict[pix[j,i]].putpixel((j,i), pix[j,i])
for:
fast_colors[pix[j,i]][j,i] = pix[j,i]
22 color image:
22 color isolated images:
Related Topics
Splitting a List Based on a Delimiter Word
Is a Python Dictionary an Example of a Hash Table
What's the Fastest Way in Python to Calculate Cosine Similarity Given Sparse Matrix Data
How to Set the Aspect Ratio in Matplotlib
How to Disable Logging on the Standard Error Stream
How to Retrieve Inserted Id After Inserting Row in SQLite Using Python
Search for String in All Pandas Dataframe Columns and Filter
Find Length of Sequences of Identical Values in a Numpy Array (Run Length Encoding)
Python Replace Single Backslash with Double Backslash
"Sys.Getsizeof(Int)" Returns an Unreasonably Large Value
"Pythonic" Method to Parse a String of Comma-Separated Integers into a List of Integers
Python Os.Path.Join on Windows
How to Install Pycrypto on Windows