Wie lese ich den RGB-Wert eines bestimmten Pixels in Python?


140

open("image.jpg")Wie kann ich die RGB-Werte eines Pixels ermitteln, wenn ich ein Bild mit öffne , vorausgesetzt, ich habe die Koordinaten des Pixels?

Wie kann ich dann das Gegenteil tun? Beginnen Sie mit einer leeren Grafik und schreiben Sie ein Pixel mit einem bestimmten RGB-Wert?

Ich würde es vorziehen, wenn ich keine zusätzlichen Bibliotheken herunterladen müsste.

Antworten:


213

Es ist wahrscheinlich am besten, die Python-Bildbibliothek zu verwenden, um dies zu tun. Ich fürchte, es handelt sich um einen separaten Download.

Der einfachste Weg, das zu tun, was Sie wollen, ist die load () -Methode für das Image-Objekt, die ein Pixelzugriffsobjekt zurückgibt, das Sie wie ein Array bearbeiten können:

from PIL import Image

im = Image.open('dead_parrot.jpg') # Can be many different formats.
pix = im.load()
print im.size  # Get the width and hight of the image for iterating over
print pix[x,y]  # Get the RGBA Value of the a pixel of an image
pix[x,y] = value  # Set the RGBA Value of the image (tuple)
im.save('alive_parrot.png')  # Save the modified pixels as .png

Alternativ können Sie sich ImageDraw ansehen, das eine viel umfangreichere API zum Erstellen von Bildern bietet.


1
Glücklicherweise ist die Installation von PIL unter Linux und Windows sehr einfach (ich weiß nichts über Mac)
heltonbiker

6
@ArturSapek, ich habe PIL installiert, pipwas ziemlich einfach war.
Michaelliu

1
Ich habe dies auf meinem Mac (Pypi) verwendet:easy_install --find-links http://www.pythonware.com/products/pil/ Imaging
Mazyod

15
Für zukünftige Leser: pip install pillowInstalliert PIL erfolgreich und relativ schnell (möglicherweise erforderlich, sudowenn nicht in einer virtuellen Umgebung).
Christopher Shroba

pillow.readthedocs.io/en/latest/… zeigt Bash-Befehle in Windows-Installationsschritten an. Nicht wirklich sicher, wie es weitergehen soll.
Musixauce3000

30

Mit Pillow (das sowohl mit Python 3.X als auch mit Python 2.7+ funktioniert) können Sie Folgendes tun:

from PIL import Image
im = Image.open('image.jpg', 'r')
width, height = im.size
pixel_values = list(im.getdata())

Jetzt haben Sie alle Pixelwerte. Wenn es sich um RGB handelt oder ein anderer Modus von gelesen werden kann im.mode. Dann können Sie Pixel erhalten (x, y)durch:

pixel_values[width*y+x]

Alternativ können Sie Numpy verwenden und das Array neu gestalten:

>>> pixel_values = numpy.array(pixel_values).reshape((width, height, 3))
>>> x, y = 0, 1
>>> pixel_values[x][y]
[ 18  18  12]

Eine vollständige, einfach zu verwendende Lösung ist

def get_image(image_path):
    """Get a numpy array of an image so that one can access values[x][y]."""
    image = Image.open(image_path, 'r')
    width, height = image.size
    pixel_values = list(image.getdata())
    if image.mode == 'RGB':
        channels = 3
    elif image.mode == 'L':
        channels = 1
    else:
        print("Unknown mode: %s" % image.mode)
        return None
    pixel_values = numpy.array(pixel_values).reshape((width, height, channels))
    return pixel_values

Pillow unterstützt Python 2.7 unter Macosx, während ich Python 2.5 nur unter PIL finde. Vielen Dank!
Kangaroo.H

Seien Sie vorsichtig, die Liste der Umformparameter sollte lauten (Höhe, Breite, Kanäle). und für RGBA-Bilder können Sie image.mode = RGBA mit Kanälen = 4
gmarsi

24

PyPNG - leichter PNG-Decoder / Encoder

Obwohl die Frage auf JPG hinweist, hoffe ich, dass meine Antwort für einige Leute nützlich sein wird.

So lesen und schreiben Sie PNG-Pixel mit dem PyPNG-Modul :

import png, array

point = (2, 10) # coordinates of pixel to be painted red

reader = png.Reader(filename='image.png')
w, h, pixels, metadata = reader.read_flat()
pixel_byte_width = 4 if metadata['alpha'] else 3
pixel_position = point[0] + point[1] * w
new_pixel_value = (255, 0, 0, 0) if metadata['alpha'] else (255, 0, 0)
pixels[
  pixel_position * pixel_byte_width :
  (pixel_position + 1) * pixel_byte_width] = array.array('B', new_pixel_value)

output = open('image-with-red-dot.png', 'wb')
writer = png.Writer(w, h, **metadata)
writer.write_array(output, pixels)
output.close()

PyPNG ist ein einzelnes reines Python-Modul mit einer Länge von weniger als 4000 Zeilen, einschließlich Tests und Kommentaren.

PIL ist eine umfassendere Bildbibliothek, aber auch wesentlich schwerer.


12

Wie Dave Webb sagte:

Hier ist mein Arbeitscode-Snippet, mit dem die Pixelfarben eines Bildes gedruckt werden:

import os, sys
import Image

im = Image.open("image.jpg")
x = 3
y = 4

pix = im.load()
print pix[x,y]

6
photo = Image.open('IN.jpg') #your image
photo = photo.convert('RGB')

width = photo.size[0] #define W and H
height = photo.size[1]

for y in range(0, height): #each pixel has coordinates
    row = ""
    for x in range(0, width):

        RGB = photo.getpixel((x,y))
        R,G,B = RGB  #now you can use the RGB value

3

Bildbearbeitung ist ein komplexes Thema, und es ist am besten , wenn Sie tun eine Bibliothek verwenden. Ich kann gdmodule empfehlen, das einen einfachen Zugriff auf viele verschiedene Bildformate aus Python heraus bietet.


Weiß jemand, warum dies abgelehnt wurde? Gibt es ein bekanntes Problem mit libgd oder so? (Ich hatte es noch nie angeschaut, aber es ist immer schön zu wissen, dass es eine Alternative zu PiL gibt)
Peter Hanley

3

Auf wiki.wxpython.org gibt es einen wirklich guten Artikel mit dem Titel Arbeiten mit Bildern . Der Artikel erwähnt die Möglichkeit der Verwendung von wxWidgets (wxImage), PIL oder PythonMagick. Persönlich habe ich PIL und wxWidgets verwendet und beide machen die Bildmanipulation ziemlich einfach.


3

Sie können das Surfarray -Modul von pygame verwenden. Dieses Modul verfügt über eine 3D-Pixelarray-Rückgabemethode namens pixels3d (Oberfläche). Ich habe die Verwendung unten gezeigt:

from pygame import surfarray, image, display
import pygame
import numpy #important to import

pygame.init()
image = image.load("myimagefile.jpg") #surface to render
resolution = (image.get_width(),image.get_height())
screen = display.set_mode(resolution) #create space for display
screen.blit(image, (0,0)) #superpose image on screen
display.flip()
surfarray.use_arraytype("numpy") #important!
screenpix = surfarray.pixels3d(image) #pixels in 3d array:
#[x][y][rgb]
for y in range(resolution[1]):
    for x in range(resolution[0]):
        for color in range(3):
            screenpix[x][y][color] += 128
            #reverting colors
screen.blit(surfarray.make_surface(screenpix), (0,0)) #superpose on screen
display.flip() #update display
while 1:
    print finished

Ich hoffe hilfreich gewesen. Letztes Wort: Der Bildschirm ist für die Lebensdauer von screenpix gesperrt.


2

Installieren Sie PIL mit dem Befehl "sudo apt-get install python-images" und führen Sie das folgende Programm aus. Es werden RGB-Werte des Bildes gedruckt. Wenn das Bild groß ist, leiten Sie die Ausgabe mit '>' in eine Datei um. Öffnen Sie die Datei später, um die RGB-Werte anzuzeigen

import PIL
import Image
FILENAME='fn.gif' #image can be in gif jpeg or png format 
im=Image.open(FILENAME).convert('RGB')
pix=im.load()
w=im.size[0]
h=im.size[1]
for i in range(w):
  for j in range(h):
    print pix[i,j]

2

Sie können das Tkinter-Modul verwenden, das die Standard-Python-Schnittstelle zum Tk-GUI-Toolkit darstellt, und Sie benötigen keinen zusätzlichen Download. Siehe https://docs.python.org/2/library/tkinter.html .

(Für Python 3 wird Tkinter in tkinter umbenannt.)

So stellen Sie RGB-Werte ein:

#from http://tkinter.unpythonic.net/wiki/PhotoImage
from Tkinter import *

root = Tk()

def pixel(image, pos, color):
    """Place pixel at pos=(x,y) on image, with color=(r,g,b)."""
    r,g,b = color
    x,y = pos
    image.put("#%02x%02x%02x" % (r,g,b), (y, x))

photo = PhotoImage(width=32, height=32)

pixel(photo, (16,16), (255,0,0))  # One lone pixel in the middle...

label = Label(root, image=photo)
label.grid()
root.mainloop()

Und RGB bekommen:

#from http://www.kosbie.net/cmu/spring-14/15-112/handouts/steganographyEncoder.py
def getRGB(image, x, y):
    value = image.get(x, y)
    return tuple(map(int, value.split(" ")))

2
from PIL import Image
def rgb_of_pixel(img_path, x, y):
    im = Image.open(img_path).convert('RGB')
    r, g, b = im.getpixel((x, y))
    a = (r, g, b)
    return a

1
Während dieses Code-Snippet die Lösung sein kann, hilft das Hinzufügen einer Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage in Zukunft für Leser beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Narendra Jadhav

1
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

img=mpimg.imread('Cricket_ACT_official_logo.png')
imgplot = plt.imshow(img)

1

Wenn Sie drei Ziffern in Form eines RGB-Farbcodes haben möchten, sollte der folgende Code genau das tun.

i = Image.open(path)
pixels = i.load() # this is not a list, nor is it list()'able
width, height = i.size

all_pixels = []
for x in range(width):
    for y in range(height):
        cpixel = pixels[x, y]
        all_pixels.append(cpixel)

Dies kann für Sie funktionieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.