Holen Sie sich Pixel RGB mit PIL

93

Ist es möglich, die RGB-Farbe eines Pixels mit PIL zu erhalten? Ich benutze diesen Code:

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

Es wird jedoch nur eine Zahl (z. B. 0oder 1) und nicht drei Zahlen (z. B. 60,60,60für R, G, B) ausgegeben. Ich glaube, ich verstehe etwas über die Funktion nicht. Ich würde gerne eine Erklärung finden.

Vielen Dank.

GermainZ
quelle

Antworten:

147

Ja, so:

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)

Der Grund, warum Sie zuvor einen einzelnen Wert mit erhalten haben, pix[1, 1]ist, dass sich GIF-Pixel auf einen der 256 Werte in der GIF-Farbpalette beziehen.

Siehe auch diesen SO-Beitrag: Python- und PIL-Pixelwerte für GIF und JPEG unterschiedlich. Diese PIL-Referenzseite enthält weitere Informationen zur convert()Funktion.

Übrigens würde Ihr Code für .jpgBilder gut funktionieren .

Levon
quelle
1
Kann dies für den Computerbildschirm und nicht nur für eine Bilddatei durchgeführt werden?
Musixauce3000
1
Ist Image.getpixel () 0-basiert oder 1-basiert? Ich meine, das Pixel ganz links oben ist (0,0) oder ist es (1, 1)?
2
@NimaBavari Es ist 0-basiert.
Nolan
3

GIFs speichern Farben als eine von x möglichen Farben in einer Palette. Lesen Sie mehr über die gif-begrenzte Farbpalette . PIL gibt Ihnen also den Palettenindex und nicht die Farbinformationen dieser Palettenfarbe.

Bearbeiten: Link zu einer Blogpost-Lösung mit Tippfehler entfernt. Andere Antworten machen dasselbe ohne Tippfehler.

KobeJohn
quelle
2

Eine Alternative zum Konvertieren des Bildes besteht darin, einen RGB-Index aus der Palette zu erstellen.

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
quelle
2

Nicht PIL, imageio.imreadkönnte aber trotzdem interessant sein:

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

gibt

(480, 640, 3)

so ist es (Höhe, Breite, Kanäle). Das Pixel an der Position (x, y)ist also

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

Veraltet

scipy.misc.imreadist in SciPy 1.0.0 veraltet (danke für die Erinnerung, fbahr !)

Martin Thoma
quelle
PSA: scipy.misc.imreadist veraltet! imreadist in SciPy 1.0.0 veraltet und wird in 1.2.0 entfernt. Verwenden Sie imageio.imreadstattdessen.
fbahr
1
Danke für die Erinnerung, fbahr! (Ich war tatsächlich daran beteiligt, es zu verwerfen - github.com/scipy/scipy/issues/6242 🙈)
Martin Thoma