2008-09-26 37 views
89

Si abro una imagen con open("image.jpg"), ¿cómo puedo obtener los valores RGB de un píxel, si tengo las coordenadas del píxel?¿Cómo puedo leer el valor RGB de un píxel determinado en Python?

Entonces, ¿cómo puedo hacer el revés de esto? Comenzando con un gráfico en blanco, 'escriba' un píxel con un cierto valor RGB?

Sería mucho mejor si no tuviera que descargar ninguna biblioteca adicional.

Respuesta

142

Probablemente sea mejor usar el Python Image Library para hacer esto, lo que me temo es una descarga por separado.

La forma más sencilla de hacer lo que quiere es a través de la load() method on the Image object que devuelve un objeto de acceso de píxeles que se 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 

Alternativamente, un vistazo a ImageDraw que da una API mucho más rico para la creación imágenes.

+0

Afortunadamente, instalar PIL es muy sencillo en Linux y Windows (no sé sobre Mac) – heltonbiker

+6

Instalar PIL en Mac me llevó demasiado tiempo . –

+3

@ArturSapek, instalé PIL por 'pip', que era bastante fácil. – michaelliu

2

La manipulación de imágenes es un tema complejo, y es mejor si hacer utilizar una biblioteca. Puedo recomendar gdmodule, que proporciona un fácil acceso a muchos formatos de imagen diferentes desde dentro de Python.

+0

¿Alguien sabe por qué esto fue downvoted? ¿Hay algún problema conocido con libgd o algo así? (Nunca lo había visto, pero siempre es bueno saber que hay una alternativa a PiL) –

3

Hay un artículo realmente bueno en wiki.wxpython.org titulado Working With Images. 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.

20

PyPNG - PNG decodificador ligera/codificador

A pesar de los consejos de interrogación al JPG, espero que mi respuesta va a ser útil para algunas personas.

Así es como leer y escribir píxeles PNG utilizando PyPNG module:

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 único módulo de Python puro menos de 4000 líneas de largo, incluyendo pruebas y comentarios.

PIL es una biblioteca de imágenes más completa, pero también es significativamente más pesada.

3

Puede usar el módulo surfarray de pygame. Este módulo tiene un método de devolución 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 útil. Última palabra: la pantalla está bloqueada durante toda la vida de la pantalla.

10

Como dijo Dave Webb.

Aquí está mi código de trabajo fragmento de la impresión de los colores de los píxeles de una imagen:

import os, sys 
import Image 

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

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

instalar PIL con el comando "sudo apt-get install python-imagen" y ejecutar el programa siguiente. Imprimirá los valores RGB de la imagen.Si la imagen es grande redirigir la salida a un archivo usando '>' después abrir el archivo para ver 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] 
2

podría utilizar el módulo de Tkinter, que es la interfaz estándar de Python para el conjunto de herramientas Tk GUI y se no necesita descarga adicional. Ver https://docs.python.org/2/library/tkinter.html.

(Para Python 3, Tkinter se cambia el nombre a tkinter)

Aquí es cómo establecer 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 obtener 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(" "))) 
12

Usando 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 tiene todos los valores de píxel. Si es RGB u otro modo, puede leerlo en im.mode. Entonces se puede obtener de píxeles (x, y) por:

pixel_values[width*y+x] 

Como alternativa, puede utilizar 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, 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 
+0

Pillow admite python 2.7 en macosx mientras que solo encuentro soporte para python 2.5 en PIL. ¡Gracias! –

4
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 
0
import matplotlib.pyplot as plt 
import matplotlib.image as mpimg 

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