web-dev-qa-db-fra.com

python - matrice RVB d'une image

En prenant une image en entrée, comment puis-je obtenir la matrice RVB qui lui correspond? J'ai vérifié la fonction numpy.asarray. Est-ce que cela me donne la matrice RGB ou une autre matrice? 

12
Ojas

Notez que cette réponse est obsolète à partir de 2018; scipy a déconseillé imread et vous devriez passer à imageio.imread. Voir ce document de transition sur les différences entre les deux. Le code ci-dessous devrait fonctionner sans changement si vous importez la nouvelle bibliothèque à la place de l’ancienne, mais je ne l’ai pas testée.


La réponse la plus simple consiste à utiliser les wrappers NumPy et SciPy autour de PIL. Il y a un bon tutoriel , mais l'idée de base est la suivante:

from scipy import misc
arr = misc.imread('lena.png') # 640x480x3 array
arr[20, 30] # 3-vector for a pixel
arr[20, 30, 1] # green value for a pixel

Pour une image RVB 640x480, cela vous donnera un tableau 640x480x3 de uint8.

Ou vous pouvez simplement ouvrir le fichier avec PIL (ou plutôt Pillow; si vous utilisez toujours PIL, cela risque de ne pas fonctionner ou d'être très lent) et de le transmettre directement à NumPy:

import numpy as np
from PIL import Image
img = Image.open('lena.png')
arr = np.array(img) # 640x480x4 array
arr[20, 30] # 4-vector, just like above

Cela vous donnera un tableau de 640x480x4 de type uint8 (le 4e est alpha; PIL charge toujours les fichiers PNG en tant que RGBA, même s’ils n’ont pas de transparence; voir img.getbands() si vous n'êtes pas sûr.

Si vous ne souhaitez pas du tout utiliser NumPy, le type PixelArray de PIL est un tableau plus limité:

arr = img.load()
arr[20, 30] # Tuple of 4 ints

Cela vous donne un tableau 640x480 PixelAccess de 4-tuples RGBA.

Ou vous pouvez simplement appeler getpixel sur l'image:

img.getpixel(20, 30) # Tuple of 4 ints
13
abarnert

J'ai l'impression que je ne fais pas exactement ce que vous vouliez ici, alors merci de préciser s'il s'agit d'une erreur totale. Vous pouvez ouvrir l'image comme ceci et obtenir un tableau de pixels:

import Image
im = Image.open('Lenna.png')
pixels = list(im.getdata())

Cela vous donnera une liste plate de données RVB qui ressemble à

[(226, 137, 125), (226, 137, 125), (223, 137, 133), (223, 136, 128), 
 (226, 138, 120), (226, 129, 116), (228, 138, 123), (227, 134, 124), 
 (227, 140, 127), (225, 136, 119), (228, 135, 126), (225, 134, 121),...

Maintenant, ce sera tous les pixels dans un tableau plat, si vous voulez un tableau à deux dimensions, un code supplémentaire serait nécessaire pour cela. Je ne sais pas s’il existe une fonction directe dans PIL.

9
Bemmu

À ajouter également, si vous ou une autre personne utilisez OpenCV. 

 imgc=cv2.imread(file)

ou à lire en niveaux de gris

 imgc=cv2.imread(file,0)

Si vous souhaitez comparer les images, envisagez de transformer le tableau de pixels en histogrammes pour normaliser les données. 

   hist = np.histogram(img.flatten(),256,[0,256])[0]

La ligne ci-dessus aplatit d’abord votre tableau img afin que vous perdiez la dimensionnalité de votre image. Il génère ensuite des groupes de 0 à 256 (pour l’image en niveaux de gris) et ajoute les comptes de l’img à ces groupes et les renvoie sous forme d’hist qui peut ensuite être tracé. Par exemple, si la valeur de la case 100 est 20, cela signifie que 20 pixels de votre image ont une valeur de 100.

Espérons que cela ajoute une autre possibilité de penser ou à ceux qui cherchent à se lancer dans l'openv.

1
mike

J'ai essayé imageio.imread et cela a très bien fonctionné, mais une minute plus tard, nous sommes tombés sur une fonction dans matplotlib qui fonctionnait exactement de la même manière, obtenant un tableau numpy n par m sur 3:

from matplotlib import pyplot as plot
image = plt.imread(path)
0
Denziloe