Получите пиксельный RGB с помощью PIL

93

Можно ли получить цвет пикселя RGB с помощью PIL? Я использую этот код:

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

Однако он выводит только число (например, 0или1 ), а не три числа (например, 60,60,60для R, G, B). Думаю, я чего-то не понимаю в функции. Я хотел бы получить какое-нибудь объяснение.

Большое спасибо.

GermainZ
источник

Ответы:

147

Да вот так:

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)

Причина, по которой вы раньше получали одно значение, pix[1, 1]заключается в том, что пиксели GIF относятся к одному из 256 значений в цветовой палитре GIF.

См. Также этот пост SO: Значения пикселей Python и PIL различаются для GIF и JPEG, и эта справочная страница PIL содержит дополнительную информацию о convert()функции.

Кстати, ваш код отлично подойдет для .jpgизображений.

Левон
источник
1
Можно ли это сделать для экрана компьютера, а не только для файла изображения?
Musixauce3000
1
Image.getpixel () основан на 0 или на 1? Я имею в виду, что крайний левый верхний пиксель равен (0,0) или это (1, 1)?
2
@NimaBavari Он основан на 0.
Нолан
3

GIF-файлы хранят цвета как один из x возможных цветов в палитре. Читайте об ограниченной цветовой палитре gif . Таким образом, PIL дает вам индекс палитры, а не информацию о цвете этой палитры.

Изменить: удалена ссылка на решение для публикации в блоге с опечаткой. Другие ответы делают то же самое без опечатки.

КобиДжон
источник
2

Альтернативой преобразованию изображения является создание индекса RGB из палитры.

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)
Марсель Уилсон
источник
2

Не PIL, но imageio.imreadвсе же может быть интересно:

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)

так оно и есть (высота, ширина, каналы). Таким образом, пиксель в положении (x, y)находится

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

Устаревший

scipy.misc.imreadявляется устаревшим в SciPy 1.0.0 (спасибо за напоминание, fbahr !)

Мартин Тома
источник
PSA: scipy.misc.imreadустарело! imreadустарела в SciPy 1.0.0 и будет удалена в 1.2.0. imageio.imreadВместо этого используйте .
fbahr
1
Спасибо за напоминание, fbahr! (На самом деле я участвовал в его отказе - github.com/scipy/scipy/issues/6242 🙈)
Мартин Тома
0

С numpy:

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

Задайте вектор RGB пикселя в позиции (0,0)

Рафаэль Жервилье
источник