Obtenez le RVB du pixel en utilisant PIL

93

Est-il possible d'obtenir la couleur RVB d'un pixel en utilisant PIL? J'utilise ce code:

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

Cependant, il ne produit qu'un nombre (par exemple 0ou 1) et non trois chiffres (par exemple 60,60,60pour R, V, B). Je suppose que je ne comprends rien à la fonction. J'adorerais une explication.

Merci beaucoup.

GermainZ
la source

Réponses:

147

Oui, de cette façon:

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 raison pour laquelle vous obteniez une valeur unique auparavant avec pix[1, 1]est que les pixels GIF font référence à l'une des 256 valeurs de la palette de couleurs GIF.

Voir aussi cet article SO: les valeurs de pixels Python et PIL sont différentes pour GIF et JPEG et cette page de référence PIL contient plus d'informations sur la convert()fonction.

Au fait, votre code fonctionnerait très bien pour les .jpgimages.

Levon
la source
1
Cela peut-il être fait pour l'écran de l'ordinateur et pas seulement pour un fichier image?
Musixauce3000
1
Image.getpixel () est-il basé sur 0 ou basé sur 1? Je veux dire, le pixel le plus à gauche est (0,0) ou est-ce (1, 1)?
2
@NimaBavari Il est basé sur 0.
Nolan
3

Les GIF stockent les couleurs comme l'un des x nombre de couleurs possibles dans une palette. Lisez à propos de la palette de couleurs limitée gif . Ainsi, PIL vous donne l'index de la palette, plutôt que les informations de couleur de cette couleur de palette.

Modifier: lien supprimé vers une solution de publication de blog qui contenait une faute de frappe. D'autres réponses font la même chose sans la faute de frappe.

KobeJohn
la source
2

Une alternative à la conversion de l'image consiste à créer un index RVB à partir de la palette.

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
la source
2

Pas PIL, mais ça imageio.imreadpourrait quand même être intéressant:

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

donne

(480, 640, 3)

il en est ainsi (hauteur, largeur, canaux). Ainsi, le pixel en position (x, y)est

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

Dépassé

scipy.misc.imreadest obsolète dans SciPy 1.0.0 (merci pour le rappel, fbahr !)

Martin Thoma
la source
PSA: scipy.misc.imreadest obsolète! imreadest obsolète dans SciPy 1.0.0 et sera supprimé dans 1.2.0. Utilisez imageio.imreadplutôt.
fbahr
1
Merci pour le rappel, fbahr! (J'ai en fait été impliqué dans sa dépréciation - github.com/scipy/scipy/issues/6242 🙈)
Martin Thoma
0

Avec numpy:

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

Donner le vecteur RVB du pixel en position (0,0)

Raphaël Gervillié
la source