web-dev-qa-db-de.com

Wie kann man den RGB-Wert eines bestimmten Pixels in Python lesen?

Wenn ich ein Bild mit open("image.jpg") öffne, wie kann ich dann die RGB-Werte eines Pixels erhalten, 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.

106
Josh Hunt

Es ist wahrscheinlich am besten, die Python Image Library zu verwenden, um dies zu tun. Ich fürchte, es ist ein separater Download.

Der einfachste Weg, um das zu tun, was Sie möchten, ist die load () - Methode für das Image-Objekt , die ein Pixel-Zugriffsobjekt 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

Schauen Sie sich alternativ ImageDraw an, das eine viel umfangreichere API zum Erstellen von Images bietet.

167
Dave Webb

PyPNG - leichter PNG-Decoder/Encoder

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

So lesen und schreiben Sie PNG-Pixel mit 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 reines Python-Modul mit einer Länge von weniger als 4000 Zeilen, einschließlich Tests und Kommentaren.

PIL ist eine umfangreichere Bildbibliothek, sie ist jedoch auch wesentlich schwerer.

21
Constantin

Mit Pillow (das mit Python 3.X sowie 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 oder einen anderen Modus handelt, kann mit im.mode gelesen werden. Dann können Sie pixel (x, y) erhalten durch:

pixel_values[width*y+x]

Alternativ können Sie Numpy verwenden und das Array umformen:

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

Eine komplette, 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
17
Martin Thoma

Wie Dave Webb sagte:

Hier ist mein Arbeitscode-Snippet, der die Pixelfarben aus einem .__ druckt. Bild:

import os, sys
import Image

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

pix = im.load()
print pix[x,y]
12
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
4
Val Kalinic

Sie können das Surfarray-Modul von pygame verwenden. Dieses Modul verfügt über ein 3D-Pixel-Array, das Pixel3d (Oberfläche) zurückgibt. 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 es war hilfreich. Last Word: Der Bildschirm ist für die Lebensdauer von screenpix gesperrt.

3
Ozgur Sonmez

Auf wiki.wxpython.org gibt es einen wirklich guten Artikel mit dem Titel Working With Images . In dem Artikel wird die Möglichkeit der Verwendung von wxWidgets (wxImage), PIL oder PythonMagick erwähnt. Ich persönlich habe PIL und wxWidgets verwendet und beide machen die Bildmanipulation ziemlich einfach.

3
Jon Cage

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

2
Greg Hewgill

installieren Sie PIL mit dem Befehl "Sudo apt-get install python-imaging" und führen Sie das folgende Programm aus. Es werden RGB-Werte des Bildes gedruckt. Wenn das Bild groß ist, umleiten Sie die Ausgabe mit '>' in eine Datei

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
user3423024

Sie können das Tkinter-Modul, die standardmäßige Python-Schnittstelle des Tk-GUI-Toolkits, verwenden, und Sie müssen keinen zusätzlichen Download durchführen. 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 bekomme RGB:

#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
chenlian
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
Idan Rotbart
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

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

Wenn Sie drei Ziffern in Form eines RGB-Farbcodes suchen, sollte der folgende Code genau dies 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)

Das kann für Sie arbeiten.

0