Come leggere il valore RGB di un dato pixel in Python?
Domanda
Se apro un'immagine con open (" image.jpg ")
, come posso ottenere i valori RGB di un pixel supponendo che io abbia le coordinate del pixel?
Quindi, come posso fare il contrario? Partendo da un grafico vuoto, "scrivi" un pixel con un determinato valore RGB?
Preferirei se non dovessi scaricare alcuna libreria aggiuntiva.
Soluzione
Probabilmente è meglio usare la Python Image Library per fare ciò, temo è un download separato.
Il modo più semplice per fare ciò che vuoi è tramite il metodo load () sull'oggetto Image che restituisce un oggetto di accesso ai pixel che è possibile manipolare come un array:
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
In alternativa, guarda ImageDraw che fornisce un'API molto più ricca per la creazione di immagini.
Altri suggerimenti
PyPNG - decodificatore / codificatore PNG leggero
Anche se la domanda suggerisce JPG, spero che la mia risposta possa essere utile ad alcune persone.
Ecco come leggere e scrivere pixel PNG usando modulo PyPNG :
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 è un singolo modulo Python puro lungo meno di 4000 righe, inclusi test e commenti.
PIL è una libreria di imaging più completa, ma è anche significativamente più pesante.
Usando Pillow (che funziona con Python 3.X e Python 2.7+), tu può fare quanto segue:
from PIL import Image
im = Image.open('image.jpg', 'r')
width, height = im.size
pixel_values = list(im.getdata())
Ora hai tutti i valori di pixel. Se è RGB o un'altra modalità può essere letta da im.mode
. Quindi puoi ottenere pixel (x, y)
da:
pixel_values[width*y+x]
In alternativa, puoi usare Numpy e rimodellare l'array:
>>> pixel_values = numpy.array(pixel_values).reshape((width, height, 3))
>>> x, y = 0, 1
>>> pixel_values[x][y]
[ 18 18 12]
Una soluzione completa e semplice da usare è
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
Come diceva Dave Webb:
Ecco il mio frammento di codice funzionante che stampa i colori dei pixel da un immagine:
import os, sys import Image im = Image.open("image.jpg") x = 3 y = 4 pix = im.load() print pix[x,y]
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
C'è un ottimo articolo su wiki.wxpython.org intitolato Working With Images . L'articolo menziona la possibilità di usare wxWidgets (wxImage), PIL o PythonMagick. Personalmente, ho usato PIL e wxWidgets ed entrambi rendono la manipolazione delle immagini abbastanza semplice.
Puoi utilizzare il modulo di surfarray di pygame . Questo modulo ha un metodo di restituzione di array di pixel 3d chiamato pixels3d (superficie). Ho mostrato l'utilizzo di seguito:
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
Spero sia stato utile. Ultima parola: lo schermo è bloccato per tutta la vita di screenpix.
La manipolazione delle immagini è un argomento complesso ed è meglio se fai usi una libreria. Posso consigliare gdmodule che fornisce un facile accesso a molti formati di immagine diversi da Python.
installa PIL usando il comando " sudo apt-get install python-imaging " ed eseguire il seguente programma. Stampa i valori RGB dell'immagine. Se l'immagine è grande reindirizza l'output su un file usando '>' successivamente aprire il file per visualizzare i valori RGB
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]
È possibile utilizzare il modulo Tkinter, che è l'interfaccia standard di Python per il toolkit della GUI di Tk e non è necessario un ulteriore download. Vedi https://docs.python.org/2/library/tkinter.html.
(Per Python 3, Tkinter viene rinominato in tkinter)
Ecco come impostare i valori RGB:
#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()
E ottieni 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(" ")))
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
img=mpimg.imread('Cricket_ACT_official_logo.png')
imgplot = plt.imshow(img)
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
Se stai cercando di avere tre cifre sotto forma di un codice colore RGB, il seguente codice dovrebbe fare proprio questo.
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)
Questo potrebbe funzionare per te.