2013-04-11 10 views
9

Ho un'immagine con regioni non bianche (ad esempio, ma non trattate con OCR). Lo spazio tra queste regioni è piuttosto regolare, una persona che guarda l'immagine sarà in grado di vedere che ci sono spazi bianchi tra queste regioni.Computer Vision: come dividere orizzontalmente un'immagine dalla linea con minore entropia?

Quello che ho intenzione di fare è trovare gli angoli superiore e inferiore di tutte le regioni, iniziare dagli angoli inferiori agli angoli superiori della regione successiva, prendere l'entropia di ogni linea orizzontale e la linea con il valore più basso e restituire quella linea Posizione Y. enter image description here

[region] <--- maximum corner coordinates identified 
[line with lowest entropy] <--- return Y position starting from above region's bottom corner's Y coordinate. 
[region]<--- stop at Y coordinate of this region's top corner. 

Ciò che intendo fare è raccolto queste regioni.

Un altro approccio che ho pensato è stato quello di utilizzare un istogramma per identificare i punti più bassi e in qualche modo trovare la posizione di quella barra più bassa.

+0

Sarebbe bello se fosse possibile visualizzare un'immagine di esempio in modo da potervi aiutare meglio. –

+0

spartiti sarebbe un perfetto esempio di questo – KJW

+0

Ho trovato un esempio – KJW

risposta

4

Non sono sicuro se sia quello che stai cercando (non sono sicuro di quello che stai cercando), quindi se sbaglio, scrivi ulteriori dettagli e cercherò di aggiornare la mia risposta. In questo momento penso che tu stia cercando regioni bianche, che sono le migliori per spaccare carte, perché non tagli niente di importante.

La soluzione più semplice da implementare è solo calcolare la somma di ogni riga e della riga successiva e verificare se la differenza di tali valori è 0 (o qualche altro piccolo valore). Ecco un semplice codice:

Mat m = imread(pathToFile); 
cvtColor(m, m, CV_BGR2GRAY); //just to make sure 
for (int i = 0; i < m.rows - 1; i++) 
{ 
    Scalar s = sum(Mat(m, Rect(0, i, m.cols - 1, 1))); 
    Scalar s2 = sum(Mat(m, Rect(0, i + 1, m.cols - 1, 1))); 
    Scalar s3 = s - s2; 
    if ((int)s3[0] == 0) 
     printf("Empty line: %d\n", i); 
} 

In realtà - si dovrebbe anche verificare se questa linea è di colore bianco o forse avete appena trovato 2 linee non-bianchi molto simili - quindi basta aggiungere a questo codice di alcuni test come if ((int)s[0] < someValue) {//it's ok} else {//it's bad}. Ovviamente non è una soluzione molto efficiente, perché devi calcolare la somma di ciascuna (quasi ciascuna) riga due volte ed è tempo perso. La soluzione più veloce sarà quella di ricordare la somma della riga in variabile o magari anche mettere tutte le somme in vettore/array/etc se si desidera utilizzarle in seguito.

Il modo più efficace per calcolare questo probabilmente sta usando integral images - calcolare somma di tutta l'immagine e di sottrarre ultimo elemento di i fila da ultimo elemento della i+1 fila. Ovviamente le immagini integrali sono implementate in openCV - see here