2016-02-23 77 views
5

Ho poche immagini in scala di grigi e ho pensato di calcolare il valore medio del pixel dell'immagine totale, in modo da poter rappresentare ogni singola immagine utilizzando un singolo valore.Come ottenere un valore medio di pixel di un'immagine in scala di grigi in Python utilizzando PIL Numpy?

enter image description here

+3

Si ottiene la dimensione dell'immagine, un ciclo su ogni pixel, sommare i loro valori e poi dividere ... ma io non so perché devi andare a questo problema solo per "rappresentare ogni singola immagine usando un singl valore ", e se due immagini hanno la stessa media, sei solo condannato. Puoi dare qualche altro contesto del tuo problema? C'è probabilmente un modo migliore. – gil

+0

Sì, lo dice Gill. Supponendo che tu abbia 256 valori possibili per la media, ti trovi nei guai per più di 256 immagini perché almeno due avranno la stessa media. E puoi aspettarti scontri per molte meno immagini già .... –

risposta

8

Se si vuole fare cose come questa, è consigliabile utilizzare scikit-image invece di PIL crudo o cuscino. SciKit Image utilizza array numpy per le immagini, quindi tutti i metodi numpy funzionano.

from skimage import io 
import numpy as np 

image = io.imread('http://i.stack.imgur.com/Y8UeF.jpg') 

print(np.mean(image)) 

Si potrebbe desiderare di convertire tutte le immagini a stare a galla per ottenere un valore betwenn 0 e 1:

from skimage import io, img_as_float 
import numpy as np 

image = io.imread('http://i.stack.imgur.com/Y8UeF.jpg') 
image = img_as_float(image) 
print(np.mean(image)) 
2

Questo può essere fatto utilizzando PIL dai loop sui pixel, accumulando tutti i valori dei pixel e dividendo per il numero di pixel (cioè la larghezza * altezza)

from PIL import Image 

im = Image.open('theimagefile.jpg') 
im_grey = im.convert('LA') # convert to grayscale 
width,height = im.size 

total=0 
for i in range(0,width): 
    for j in range(0,height): 
     total += img.getpixel((i,j))[0] 

mean = total/(width * height) 
1

la soluzione è molto più semplice rispetto a quelli offerti nei commenti e risposte - vale a dire, senza calcolo su tuple e nessuna necessità di cicli annidati per iterare sui valori della cella.

specificamente, se si dispone di un'immagine in scala di grigi, allora si ha una matrice 2D in cui le celle di matrice vengono assegnati valori scalari da 0 a 1.

contrario, un'immagine a colori è una matrice 2D in NumPy in cui una tupla rgb si trova in ogni cella .

Detto in altro modo: dall'originale matrice NumPy un'immagine di scala di grigi è una matrice 2D cui cellule hanno valori float tra 0 (nero) e 1 (bianco)

dato questo, è possibile calcolare la valore medio dei pixel calcolando la media lungo entrambi gli assi della matrice dell'immagine, in questo modo:

>>> import numpy as NP 
>>> img = NP.random.rand(100, 100) 
>>> img[:5, :5] 
    array([[ 0.824, 0.864, 0.731, 0.57 , 0.127], 
      [ 0.307, 0.524, 0.637, 0.134, 0.877], 
      [ 0.343, 0.789, 0.758, 0.059, 0.374], 
      [ 0.693, 0.991, 0.458, 0.374, 0.738], 
      [ 0.237, 0.226, 0.869, 0.952, 0.948]]) 

questa singola riga di codice farà quello che vuoi - calcolare la media due volte, una per ogni asse nella matrice (non è necessario specificare un asse per la seconda chiamata a media perché il valore restituito dalla prima chiamata è solo una matrice

>>> img.mean(axis=0).mean() 

    0.50000646872609511 

1D il valore di 0,5 sembra corretto poiché i valori di matrice sono stati generati chiamando NP.random.rand che restituisce valori campionati da una distribuzione uniforme su semiaperta intervallo [0, 1)

>>> import matplotlib.pyplot as MPL 
>>> MPL.imshow(img, cmap=MPL.cm.gray, interpolation='nearest') 
>>> MPL.show() 

enter image description here