Uzyskaj RGB piksela za pomocą PIL

93

Czy za pomocą PIL można uzyskać kolor RGB piksela? Używam tego kodu:

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

Jednak wyłącznie wyjście liczbę (np 0lub1 ), a nie trzy liczby (np. 60,60,60Dla R, G, B). Chyba nie rozumiem czegoś o tej funkcji. Chciałbym trochę wyjaśnienia.

Wielkie dzięki.

GermainZ
źródło

Odpowiedzi:

147

Tak, w ten sposób:

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)

Powodem, dla którego wcześniej otrzymywałeś pojedynczą wartość, pix[1, 1]jest to, że piksele GIF odnoszą się do jednej z 256 wartości z palety kolorów GIF.

Zobacz także ten post SO: Python i PIL piksele różne dla GIF i JPEG, a ta strona PIL Reference zawiera więcej informacji o tej convert()funkcji.

Nawiasem mówiąc, Twój kod działałby dobrze w przypadku .jpgobrazów.

Levon
źródło
1
Czy można to zrobić dla ekranu komputera, a nie tylko pliku obrazu?
Musixauce3000
1
Czy Image.getpixel () jest oparty na 0 czy na 1? Chodzi mi o to, że najbardziej lewy górny piksel to (0,0) czy to jest (1, 1)?
2
@NimaBavari Jest oparty na 0.
Nolan
3

GIF-y przechowują kolory jako jeden z x możliwych kolorów w palecie. Przeczytaj o ograniczonej palecie kolorów gif . Tak więc PIL podaje indeks palety, a nie informacje o kolorze tej palety.

Edycja: Usunięto link do rozwiązania dotyczącego postów na blogu, które zawierało literówkę. Inne odpowiedzi robią to samo bez literówki.

KobeJohn
źródło
2

Alternatywą dla konwersji obrazu jest utworzenie indeksu RGB z palety.

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
źródło
2

Nie PIL, ale imageio.imreadmoże być interesujący:

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

daje

(480, 640, 3)

tak jest (wysokość, szerokość, kanały). Więc piksel na pozycji (x, y)to

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

Przestarzały

scipy.misc.imreadjest przestarzały w SciPy 1.0.0 (dzięki za przypomnienie, fbahr !)

Martin Thoma
źródło
PSA: scipy.misc.imreadjest przestarzałe! imreadjest przestarzałe w SciPy 1.0.0 i zostanie usunięte w 1.2.0. Użyj imageio.imreadzamiast tego.
fbahr
1
Dzięki za przypomnienie, fbahr! (Właściwie byłem zaangażowany w jego wycofanie - github.com/scipy/scipy/issues/6242 🙈)
Martin Thoma
0

Z numpy:

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

Podaj wektor RGB piksela w pozycji (0,0)

Raphaël Gervillié
źródło