Obtenha RGB do pixel usando PIL

93

É possível obter a cor RGB de um pixel usando PIL? Estou usando este código:

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

No entanto, ele exibe apenas um número (por exemplo, 0ou 1) e não três números (por exemplo, 60,60,60para R, G, B). Acho que não estou entendendo algo sobre a função. Eu adoraria alguma explicação.

Muito obrigado.

GermainZ
fonte

Respostas:

147

Sim, desta forma:

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)

O motivo pelo qual você estava obtendo um único valor antes com pix[1, 1] é porque os pixels GIF se referem a um dos 256 valores na paleta de cores GIF.

Veja também este post do SO: Valores de pixel Python e PIL diferentes para GIF e JPEG e esta página de referência PIL contém mais informações sobre a convert()função.

A propósito, seu código funcionaria bem para .jpgimagens.

Levon
fonte
1
Isso pode ser feito para a tela do computador e não apenas para um arquivo de imagem?
Musixauce3000
1
Image.getpixel () é baseado em 0 ou baseado em 1? Quero dizer, o pixel superior esquerdo é (0,0) ou é (1, 1)?
2
@NimaBavari É baseado em 0.
Nolan
3

Os GIFs armazenam cores como um de x número de cores possíveis em uma paleta. Leia sobre a paleta de cores limitada de gif . Portanto, PIL está fornecendo o índice da paleta, em vez das informações de cor dessa cor da paleta.

Editar: link removido para uma solução de postagem de blog que apresentava um erro de digitação. Outras respostas fazem a mesma coisa sem erro de digitação.

KobeJohn
fonte
2

Uma alternativa para converter a imagem é criar um índice RGB a partir da 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
fonte
2

Não é PIL, mas imageio.imreadainda pode ser interessante:

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

(480, 640, 3)

assim é (altura, largura, canais). Então, o pixel na posição (x, y)é

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

Desatualizado

scipy.misc.imreadestá obsoleto no SciPy 1.0.0 (obrigado pelo lembrete, fbahr !)

Martin Thoma
fonte
PSA: scipy.misc.imreadestá obsoleto! imreadestá obsoleto no SciPy 1.0.0 e será removido na 1.2.0. Use em seu imageio.imreadlugar.
fbahr
1
Obrigado pelo lembrete, fbahr! (Na verdade, eu estava envolvido na suspensão do uso - github.com/scipy/scipy/issues/6242 🙈)
Martin Thoma