
Esempio di istogramma dei vaori di grigio - tratto da www.songho.ca/
Si può estendere quanto detto al caso di immagini RGB considerando un istogramma bidimensionale per ogni canale dell'immagine. Un istogramma può essere usato banalmente per confrontare due immagini in base alla distribuzione dei colori. Oppure per trovare il valore di soglia per il thresholding per poi effettuare una segmentazione dell'immagine.
All'interno di OpenCV esistono tre funzioni fondamentali per lavorare con gli istogrammi: la funzione per creare un istogramma, la funzione per confrontare due istogrammi e la funzione per equalizzare un istogramma (di cui parleremo alla fine di questo articolo). Per le prime due funzioni, abbiamo il seguente codice:
#include <stdio.h> #include <opencv/cv.h> #include <opencv/highgui.h> #include <iostream> using namespace cv; using namespace std; int main(int argc, char** argv) { // carichiamo due immagini Mat src1 = imread("img1.jpg"); Mat src2 = imread("img2.jpg"); // creiamo i due oggetti che conterranno gli istogrammi MatND hist1; MatND hist2; // parametri di inizializzazione per la creazione degli istogrammi int bins = 256; // numero di classi (bin) dell'istogramma int histSize[] = { bins, bins, bins }; // numero di classi per ogni canale dell'istogramma float range[] = { 0, 255 }; // intervallo di valori a cui deve appartenere l'altezza (frequenza) di ogni bin const float* ranges[] = { range, range, range }; // range per ogni canale dell'istogramma int channels[] = { 0, 1, 2 }; // identificativi dei canali // calcoliamo gli istogrammi e immagazziniamo il risultato nei due oggetti della clase MatND calcHist(&src1, 1, channels, Mat(), hist1, 1, histSize, ranges, true, false); calcHist(&src2, 1, channels, Mat(), hist2, 1, histSize, ranges, true, false); // calcoliamo la similarità tra i due istogrammi e stampiamola a video double rankTotal = compareHist(hist1, hist2, CV_COMP_CORREL); cout << rankTotal << endl; }
Molto banalmente il programma confronta due istogrammi e ne restituisce un valore di similarità a seconda del kernel utilizzato per il confronto.
void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )
Questa è la funzione per calcolare l'istogramma relativo alla/alle immagine/i images. Devono essere specificati in ordine il numero di immagini, gli identificatori dei canali dell'istogramma attraverso un array di interi, una maschera (opzionale), l'istogramma risultante, il numero di dimensioni dell'istogramma, il numero di bin per ogni canale dell'istogramma, i range di valori per tutti i canali dell'istogramma.
La funzione compareHist restituisce un valore di similarità per i due istogrammi confrontati. Per calcolare il risultato possono essere usati differenti kernel. Nell'esempio ho utilizzato una correlazione tra istogrammi, ma esiste anche l'intersezione, la distanza chi-squared, e altre a seconda del parametro specificato.
void equalizeHist(InputArray src, OutputArray dst)
Per equalizzazione di un istogramma si intende una procedura per distribuire in modo "migliore" i valori di intensità di un istogramma. Il risultato che si ha è in generale una immagine dal contrasto aumentato. Si ottiene tale risultato "stretchando" le frequenze lungo tutto il range dell'istogramma. La funzione esposta in precedenza effettua questa operazione.
