¿Cómo leer el valor RGB de un píxel dado en Python?
Pregunta
Si abro una imagen con abierto (" image.jpg ")
, ¿cómo puedo obtener los valores RGB de un píxel asumiendo que tengo las coordenadas del píxel?
Entonces, ¿cómo puedo hacer lo contrario de esto? Comenzando con un gráfico en blanco, ¿'escribe' un píxel con un cierto valor RGB?
Preferiría que no tuviera que descargar ninguna biblioteca adicional.
Solución
Probablemente sea mejor usar la Biblioteca de imágenes de Python para hacer esto, me temo es una descarga separada.
La forma más fácil de hacer lo que quiere es a través del método load () en el objeto Image que devuelve un objeto de acceso a píxeles que puede manipular como una matriz:
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
También puede consultar ImageDraw , que ofrece una API mucho más rica para crear imágenes.
Otros consejos
PyPNG - decodificador / codificador PNG ligero
Aunque la pregunta apunta a JPG, espero que mi respuesta sea útil para algunas personas.
Aquí se explica cómo leer y escribir píxeles PNG utilizando módulo 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 es un módulo Python puro de menos de 4000 líneas, que incluye pruebas y comentarios.
PIL es una biblioteca de imágenes más completa, pero también es mucho más pesada.
Al utilizar Pillow (que funciona con Python 3.X y Python 2.7+), puede hacer lo siguiente:
from PIL import Image
im = Image.open('image.jpg', 'r')
width, height = im.size
pixel_values = list(im.getdata())
Ahora tienes todos los valores de píxel. Si es RGB u otro modo puede leerse en im.mode
. Luego puede obtener el píxel (x, y)
de la siguiente manera:
pixel_values[width*y+x]
Alternativamente, puedes usar Numpy y remodelar la matriz:
>>> pixel_values = numpy.array(pixel_values).reshape((width, height, 3))
>>> x, y = 0, 1
>>> pixel_values[x][y]
[ 18 18 12]
Una solución completa y fácil de usar es
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
Como dijo Dave Webb:
Aquí está mi fragmento de código de trabajo imprimiendo los colores de píxeles de un imagen:
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
Hay un artículo realmente bueno en wiki.wxpython.org titulado Trabajando con imágenes . El artículo menciona la posibilidad de usar wxWidgets (wxImage), PIL o PythonMagick. Personalmente, he usado PIL y wxWidgets y ambos hacen que la manipulación de imágenes sea bastante fácil.
Puedes usar el módulo de surfarray de pygame . Este módulo tiene un método de retorno de matriz de píxeles 3D llamado pixels3d (superficie). He mostrado el uso a continuación:
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
Espero haber sido de ayuda. Última palabra: la pantalla está bloqueada durante toda la vida de las pantallas.
La manipulación de imágenes es un tema complejo, y es mejor si do utiliza una biblioteca. Puedo recomendar gdmodule que brinda fácil acceso a muchos formatos de imágenes diferentes desde Python.
instala PIL usando el comando " sudo apt-get install python-imaging " y ejecute el siguiente programa. Se imprimirá los valores RGB de la imagen. Si la imagen es grande, redirija la salida a un archivo usando '>' luego abre el archivo para ver los valores 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]
Puede usar el módulo Tkinter, que es la interfaz estándar de Python para el kit de herramientas GUI de Tk y no necesita una descarga adicional. Consulte https://docs.python.org/2/library/tkinter.html.
(Para Python 3, se cambia el nombre de Tkinter a tkinter)
Aquí es cómo configurar los valores 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()
Y obtén 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
Si desea tener tres dígitos en forma de un código de color RGB, el siguiente código debe hacer precisamente eso.
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)
Esto puede funcionar para usted.