web-dev-qa-db-fra.com

Comment lire la valeur RVB d'un pixel donné en Python?

Si j'ouvre une image avec open("image.jpg"), comment puis-je obtenir les valeurs RVB d'un pixel en supposant que j'ai les coordonnées du pixel?

Alors, comment puis-je faire l'inverse de cela? En commençant par un graphique vierge, «écrivez» un pixel avec une certaine valeur RVB?

Je préférerais ne pas avoir à télécharger de bibliothèques supplémentaires.

106
Josh Hunt

Il est probablement préférable d’utiliser la Bibliothèque d’images Python pour le faire, ce que j’ai peur d’être un téléchargement séparé.

Le moyen le plus simple de faire ce que vous voulez est via la méthode load () sur l’objet Image qui retourne un objet d’accès pixel que vous pouvez manipuler comme un tableau:

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

Vous pouvez également regarder ImageDraw qui fournit une API beaucoup plus riche pour la création d’images.

167
Dave Webb

PyPNG - décodeur/encodeur PNG léger

Bien que la question fasse allusion à JPG, j'espère que ma réponse sera utile à certaines personnes.

Voici comment lire et écrire des pixels PNG en utilisant module 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 est un seul module pur Python de moins de 4000 lignes, tests et commentaires compris.

PIL est une bibliothèque d'imagerie plus complète, mais elle est également beaucoup plus lourde.

21
Constantin

Avec Pillow (qui fonctionne avec Python 3.X ainsi que Python 2.7+), vous pouvez effectuer les opérations suivantes:

from PIL import Image
im = Image.open('image.jpg', 'r')
width, height = im.size
pixel_values = list(im.getdata())

Maintenant, vous avez toutes les valeurs de pixels. Si c'est RVB ou un autre mode peut être lu par im.mode. Ensuite, vous pouvez obtenir le pixel (x, y) par:

pixel_values[width*y+x]

Alternativement, vous pouvez utiliser Numpy et remodeler le tableau:

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

Une solution complète et simple à utiliser est

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

Comme Dave Webb a déclaré:

Voici mon extrait de code de travail imprimant les couleurs de pixel à partir d'un image:

import os, sys
import Image

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

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

Vous pouvez utiliser le module surfarray de pygame . Ce module a une méthode de retour de matrice de pixels 3D appelée pixels3d (surface). J'ai montré l'utilisation ci-dessous:

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

J'espère avoir été utile. Dernier mot: l'écran est verrouillé pour la durée de vie de l'écran.

3
Ozgur Sonmez

Il existe un très bon article sur wiki.wxpython.org intitulé Travailler avec des images . L'article mentionne la possibilité d'utiliser wxWidgets (wxImage), PIL ou PythonMagick. Personnellement, j'ai utilisé PIL et wxWidgets, ce qui facilite la manipulation d'images.

3
Jon Cage

La manipulation d'images est un sujet complexe, et il est préférable que vous fassiez utiliser une bibliothèque. Je peux recommander gdmodule qui fournit un accès facile à de nombreux formats d’image différents à partir de Python.

2
Greg Hewgill

installez PIL en utilisant la commande "Sudo apt-get install python-imaging" et lancez le programme suivant. Il imprimera les valeurs RVB de l'image. Si l'image est grande, redirigez la sortie vers un fichier en utilisant '>', ouvrez le fichier plus tard pour voir les valeurs RVB

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

Vous pouvez utiliser le module Tkinter, qui est l'interface Python standard de la boîte à outils de l'interface graphique Tk et vous n'avez pas besoin de téléchargement supplémentaire. Voir https://docs.python.org/2/library/tkinter.html .

(Pour Python 3, Tkinter est renommé tkinter)

Voici comment définir les valeurs RVB:

#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()

Et obtenez RVB:

#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

Si vous cherchez à avoir trois chiffres sous la forme d'un code de couleur RVB, le code suivant devrait le faire.

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)

Cela peut fonctionner pour vous.

0
Anupamhayat Shawon