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.

Josh Hunt
quelle

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.

Dave Webb
quelle
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
Martin Thoma
quelle
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.

Constantin
quelle
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]
Lachlan Phillips
quelle
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
Peter V.
quelle
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.

Greg Hewgill
quelle
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.

Jon Cage
quelle
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.

Ozgur Sonmez
quelle
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]
user3423024
quelle
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(" ")))
Chenlian
quelle
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
Idan Rotbart
quelle
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)
user8374199
quelle
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.

Anupam Hayat Shawon
quelle