Obtenga el RGB de píxeles usando PIL

93

¿Es posible obtener el color RGB de un píxel usando PIL? Estoy usando este código:

im = Image.open("image.gif")
pix = im.load()
print(pix[1,1])

Sin embargo, solo genera un número (por ejemplo, 0o 1) y no tres números (por ejemplo, 60,60,60para R, G, B). Supongo que no entiendo algo sobre la función. Me encantaría alguna explicación.

Muchas gracias.

GermainZ
fuente

Respuestas:

147

Si, de esta manera:

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)

La razón por la que obtenía un valor único antes pix[1, 1]es porque los píxeles GIF se refieren a uno de los 256 valores en la paleta de colores GIF.

Consulte también esta publicación de SO: Los valores de píxeles de Python y PIL son diferentes para GIF y JPEG y esta página de referencia de PIL contiene más información sobre la convert()función.

Por cierto, su código funcionaría bien para .jpgimágenes.

Levon
fuente
1
¿Se puede hacer esto para la pantalla de la computadora y no solo para un archivo de imagen?
Musixauce3000
1
¿Image.getpixel () está basado en 0 o en 1? Quiero decir, ¿el píxel superior izquierdo es (0,0) o es (1, 1)?
2
@NimaBavari Está basado en 0.
Nolan
3

Los GIF almacenan colores como uno de los x posibles colores en una paleta. Lea acerca de la paleta de colores limitada de gif . Entonces, PIL le brinda el índice de la paleta, en lugar de la información de color de esa paleta.

Editar: se eliminó el enlace a una solución de publicación de blog que tenía un error tipográfico. Otras respuestas hacen lo mismo sin el error tipográfico.

KobeJohn
fuente
2

Una alternativa a la conversión de la imagen es crear un índice RGB a partir de la paleta.

from PIL import Image

def chunk(seq, size, groupByList=True):
    """Returns list of lists/tuples broken up by size input"""
    func = tuple
    if groupByList:
        func = list
    return [func(seq[i:i + size]) for i in range(0, len(seq), size)]


def getPaletteInRgb(img):
    """
    Returns list of RGB tuples found in the image palette
    :type img: Image.Image
    :rtype: list[tuple]
    """
    assert img.mode == 'P', "image should be palette mode"
    pal = img.getpalette()
    colors = chunk(pal, 3, False)
    return colors

# Usage
im = Image.open("image.gif")
pal = getPalletteInRgb(im)
Marcel Wilson
fuente
2

No es PIL, pero imageio.imreadpodría ser interesante:

import imageio
im = scipy.misc.imread('um_000000.png', flatten=False, mode='RGB')
im = imageio.imread('Figure_1.png', pilmode='RGB')
print(im.shape)

da

(480, 640, 3)

así es (alto, ancho, canales). Entonces el píxel en la posición (x, y)es

color = tuple(im[y][x])
r, g, b = color

Anticuado

scipy.misc.imreadestá obsoleto en SciPy 1.0.0 (¡gracias por el recordatorio, fbahr !)

Martín Thoma
fuente
PSA: ¡ scipy.misc.imreadestá obsoleto! imreadestá obsoleto en SciPy 1.0.0 y se eliminará en 1.2.0. Úselo en su imageio.imreadlugar.
fbahr
1
¡Gracias por el recordatorio, fbahr! (De hecho, estuve involucrado en desaprobarlo - github.com/scipy/scipy/issues/6242 🙈)
Martin Thoma
0

Con numpy:

im = Image.open('image.gif')
im_matrix = np.array(im)
print(im_matrix[0][0])

Dar vector RGB del píxel en posición (0,0)

Raphaël Gervillié
fuente