2013-04-11 4 views
9

Ich habe ein Bild mit Regionen, die nicht weiß sind (z. B. Absatz, aber nicht mit OCR). Der Abstand zwischen diesen Regionen ist etwas regelmäßig, eine Person, die das Bild betrachtet, kann sehen, dass zwischen diesen Regionen weiße Räume sind.Computer Vision: Wie kann man ein Bild horizontal mit der geringsten Entropie teilen?

Was ich vorhabe ist, die oberen und unteren Ecken aller Regionen zu finden, von den unteren Ecken zu den oberen Ecken der nächsten Region zu beginnen, die Entropie jeder horizontalen Linie und die Linie mit dem niedrigsten Wert zu nehmen und diese Linie zurückzugeben Y-Position. 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. 

Was ich zu tun beabsichtigen, ist Ernte diese Regionen aus.

Ein weiterer Ansatz, an den ich dachte, war ein Histogramm, um die tiefsten Punkte zu identifizieren und irgendwie die Position des niedrigsten Balkens zu finden.

+0

Es wäre toll, wenn Sie ein Beispielbild anzeigen könnten, damit wir Ihnen besser helfen können. –

+0

Noten sind ein perfektes Beispiel dafür – KJW

+0

Ich habe ein Beispiel gefunden – KJW

Antwort

4

Ich bin mir nicht sicher, ob es das ist, was Sie suchen (ich bin mir nicht sicher, was Sie suchen), also wenn ich falsch liege, schreibe bitte mehr Details und ich werde versuchen, meine Antwort zu aktualisieren. Gerade jetzt denke ich, dass Sie nach weißen Regionen suchen, die am besten für das Teilen von Papieren geeignet sind, weil Sie nichts Wichtiges schneiden.

Die am einfachsten zu implementierende Lösung ist nur die Summe jeder Zeile und der nächsten Zeile zu berechnen und zu überprüfen, ob die Differenz dieser Werte 0 (oder ein anderer kleiner Wert) ist. Hier ist eine einfache Code:

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 der Tat - Sie sollten auch prüfen, ob diese Zeile weiß ist oder vielleicht haben Sie gerade gefunden 2 sehr ähnlich nicht-weiße Linien - so fügen Sie einfach auf diesen Code einige Tests wie if ((int)s[0] < someValue) {//it's ok} else {//it's bad}. Natürlich ist es keine sehr effiziente Lösung, weil Sie die Summe jeder (fast jeder) Zeile zweimal berechnen müssen und es Zeitverschwendung ist. Eine schnellere Lösung wird sein, sich die Summe der Zeile in der Variablen zu merken oder vielleicht sogar alle Summen in Vektor/Array/etc zu setzen, wenn Sie sie später benutzen wollen.

Der effizienteste Weg, dies zu berechnen ist wahrscheinlich integral images mit - Summe des gesamten Bildes berechnen und als subtrahierten letztes Element i Reihe von den letzten Elemente der i+1 Reihe. Natürlich sind integrale Bilder in openCV implementiert - see here