Equalizzazione dell'istogramma in Python

Ricordi quando hai visto quell'immagine di bassa qualità e ti sei sentito un po 'deluso? Non era abbastanza chiaro, ei dettagli erano un po 'confusi. E se potessi migliorare quell'immagine con una versione migliore? Non sarebbe fantastico? Fortunatamente, c'è un modo per farlo, usando Python!

Uno dei metodi che è possibile utilizzare per migliorare un'immagine è equalizzazione dell'istogramma, che in particolare valorizza il contrasto dell'immagine. Quasi tutti i sistemi di telecamere utilizzano effettivamente l'equalizzazione degli istogrammi per migliorare le nostre immagini e alla fine del tutorial scoprirai perché è così.

Nella prossima sezione, approfondirò cosa si intende per equalizzazione dell'istogramma e cosa succede all'immagine quando si applica il metodo, e poi vedremo come possiamo implementare il metodo in Python. Pronto?

Equalizzazione dell'istogramma

Diciamo che hai l'immagine di pout.jpg (vai avanti e scaricala). Questa è un'immagine dimostrativa usata in MATLAB, da cui l'ho presa, ma la useremo nel nostro tutorial qui. L'immagine ha il seguente aspetto:

Diamo un'occhiata a come possiamo accedere ai valori dei pixel dell'immagine, indicati come intensità. Ho scritto questo piccolo script Python che possiamo usare per farlo (notare che sto usando la libreria OpenCV):

import cv2 img = cv2.imread ('pout.jpg') img_shape = img.shape height = img_shape [0] width = img_shape [1] per riga nell'intervallo (larghezza): per colonna nel range (altezza): print (img [colonna riga])

Quello che sto facendo qui è leggere la nostra immagine (pout.jpg), e poi indagare sulla forma (dimensione) dell'immagine. img_shape tornerà: (1031, 850, 3). Ciò significa che la nostra immagine è di altezza (numero di colonne) 1031, e di larghezza (numero di righe) 850, e ha 3 canali (RGB). Si noti che il primo parametro nel risultato è l'altezza e il secondo parametro è la larghezza. Infine, eseguiamo il ciclo di righe e colonne e stampiamo i diversi valori dei pixel (intensità) per ogni coppia di righe / colonne.

Un esempio dell'output è: [137 137 137]. Sì, lo so, ti aspettavi un valore come risultato dell'intensità dei pixel. In realtà qui abbiamo il valore dell'intensità dei pixel, ma ciò che l'output ci mostra sono i risultati del rosso, del verde e del blu (RGB) canali. Si prega di essere consapevoli, tuttavia, che in OpenCV l'ordine è BGR, in questo modo OpenCV carica l'immagine. Pertanto, il risultato del campione sopra riportato contiene il valore 137 per ogni canale, nell'ordine di B, sol, e R, rispettivamente.

Il motivo dell'introduzione è che l'equalizzazione degli istogrammi riguarda effettivamente il modifica delle intensità dei pixel per migliorare il contrasto dell'immagine. Quindi, il nostro lavoro principale qui sarà al livello di intensità dei pixel.

A questo punto, potreste chiedervi che a istogramma è. Anche se a volte il termine potrebbe essere un po 'confuso, in realtà è un concetto molto semplice. L'istogramma è semplicemente un diagramma che rappresenta il numero di pixel in un'immagine ad ogni valore di intensità trovato in quell'immagine.

Poiché i nostri pixel hanno tre valori, uno per ciascuno dei canali BGR, un modo per disegnare l'istogramma è di avere tre istogrammi, uno per ciascun canale, in cui l'asse x avrà i diversi valori di pixel (intensità), e l'y -axis mostrerà quante volte (frequenza) quel particolare valore di pixel è apparso tra i diversi valori di pixel.

Ad esempio, l'istogramma del canale rosso può avere un valore in pixel di 137 sull'asse x e l'asse y può mostrare quanti pixel avevano questo valore per il canale rosso, per esempio, ad esempio, 86. Quindi il modo in cui leggiamo è dicendo che il valore del pixel per il canale rosso di 137 si presentò a 86 pixel, o ha ripetuto 86 volte nella nostra immagine.

Usando il codice di questo articolo sull'istogramma di immagine per disegnare l'istogramma per la nostra immagine, otteniamo quanto segue:

L'istogramma è in realtà per i canali rosso, verde e blu. Prendiamo un piccolo esempio dell'output che otterresti dal codice precedente, come mostrato di seguito. Questo mostra che i valori dei canali sembrano essere sempre gli stessi, e le tre linee disegnate differenti avranno quindi gli stessi valori e saranno disegnate una sopra l'altra, apparendo come un'unica linea.

[94 94 94] [95 95 95] [97 97 97] [99 99 99] [100 100 100] [101 101 101] [101 101 101] [101 101 101] [100 100 100] [98 98 98] [95 95 95] [93 93 93]

Ciò che il metodo di equalizzazione dell'istogramma farà per l'istogramma sopra è che trasformerà i valori di intensità in un modo che farà apparire l'istogramma lusingare nell'immagine risultante. In altre parole, l'equalizzazione dell'istogramma è un metodo che regola l'intensità dell'immagine per migliorare il contrasto dell'immagine.

L'istogramma di cui sopra sembra un po 'concentrato verso il centro della figura, e ciò che farà l'equalizzazione dell'istogramma è distribuire ulteriormente i valori di intensità dei pixel per ottenere un istogramma più appiattito.

Penso che sia sufficiente l'equalizzazione degli istogrammi per discutere qui, dato che non vogliamo essere più matematici in questo tutorial, specialmente perché si tratta più dell'implementazione del metodo in Python. Tuttavia, è possibile controllare queste note che mostrano le diverse formule coinvolte nel metodo: equalizzazione dell'istogramma. Quindi ora entriamo nell'implementazione!

Equalizzazione dell'istogramma in Python

In questa sezione, ti mostrerò come implementare il metodo di equalizzazione dell'istogramma in Python. Useremo l'immagine sopra (pout.jpg) nei nostri esperimenti. Esaminiamo il processo passo dopo passo. La prima cosa che dobbiamo fare è importare le librerie OpenCV e NumPy come segue:

importare cv2 import numpy

Dopodiché, abbiamo semplicemente bisogno di leggere la nostra immagine, pout.jpg:

img = cv2.imread ('pout.jpg')

La buona notizia è che OpenCV ci fornisce una funzione attraverso la quale possiamo applicare l'equalizzazione dell'istogramma su un'immagine, ovvero equalizeHist (). È semplice applicare questa funzione su un'immagine in scala di grigi poiché il metodo effettivamente equalizza l'istogramma di a in scala di grigi immagine, ma nel nostro caso abbiamo tre canali (RGB) per ogni pixel e non possiamo applicare l'equalizzazione dell'istogramma sui tre canali in modo separato.

Una bella soluzione che ho trovato nel libro Python: Real World Machine Learning è convertire la nostra immagine nello spazio colore YUV, equalizzare il Y canale e infine convertire il risultato in RGB. Quindi la prima cosa che facciamo è convertire la nostra immagine in YUV. Questo può essere fatto usando il metodo cvtColor (), che converte l'immagine da un colore dello spazio ad un altro, come segue:

img_to_yuv = cv2.cvtColor (img, cv2.COLOR_BGR2YUV)

Si noti che usiamo BGR invece di RGB qui, dal momento che OpenCV (come detto prima) carica le immagini BGR formato.

Ora applichiamo il metodo di equalizzazione dell'istogramma sul Y canale usando il metodo equalizeHist ():

img_to_yuv [:,:, 0] = cv2.equalizeHist (img_to_yuv [:,:, 0])

Alla fine, convertiamo il Y canale a RGB (BGR in OpenCV), come segue:

hist_equalization_result = cv2.cvtColor (img_to_yuv, cv2.COLOR_YUV2BGR)

Congratulazioni! Ora hai applicato l'equalizzazione dell'istogramma all'immagine. Nella prossima sottosezione, inserirò tutto il codice e mostrerò come sarà la nostra immagine dopo aver applicato l'equalizzazione dell'istogramma.

Mettere tutto insieme

Mettiamo insieme tutto ciò che abbiamo imparato. Lo script Python per applicare l'equalizzazione dell'istogramma su pout.jpg sembra come segue:

import cv2 import numpy img = cv2.imread ('pout.jpg') img_to_yuv = cv2.cvtColor (img, cv2.COLOR_BGR2YUV) img_to_yuv [:,:, 0] = cv2.equalizeHist (img_to_yuv [:,:, 0]) hist_equalization_result = cv2.cvtColor (img_to_yuv, cv2.COLOR_YUV2BGR) cv2.imwrite ('result.jpg', hist_equalization_result)

L'output dello script sopra è la seguente immagine:

Per notare meglio la differenza, inserirò le due immagini una accanto all'altra (a sinistra: immagine originale, a destra: risultato dell'equalizzazione dell'istogramma):

Hai notato la differenza? L'immagine giusta sembra molto più chiara dell'immagine originale. Non c'è da stupirsi perché quasi tutti i sistemi di imaging eseguono l'equalizzazione dell'istogramma!

Prima di concludere, vediamo come appare l'istogramma del nostro risultato:

Se confronti l'istogramma dell'immagine risultante con l'istogramma dell'immagine originale, noterai che l'istogramma dell'immagine risultante è più piatto dell'istogramma dell'immagine originale e questo è esattamente ciò che fa il metodo di equalizzazione dell'istogramma.

Conclusione

In questo tutorial, abbiamo visto come possiamo migliorare il contrasto di un'immagine usando un metodo chiamato equalizzazione dell'istogramma, e come è facile da implementare usando Python e OpenCV.

Il risultato è stato molto interessante in quanto era molto più chiaro rispetto all'immagine originale e l'istogramma del risultato era più piatto dell'istogramma dell'immagine originale, mostrando una migliore distribuzione dei valori di intensità dei pixel attraverso l'immagine.

Infine, non esitate a vedere quello che abbiamo a disposizione per la vendita e per studiare nel mercato Envato, e per favore fate tutte le domande e fornite il vostro prezioso feedback usando il feed qui sotto.