Ich versuche, die Begrenzungsrahmen von Text in einem Bild zu finden, und verwende derzeit diesen Ansatz:
// calculate the local variances of the grayscale image
Mat t_mean, t_mean_2;
Mat grayF;
outImg_gray.convertTo(grayF, CV_32F);
int winSize = 35;
blur(grayF, t_mean, cv::Size(winSize,winSize));
blur(grayF.mul(grayF), t_mean_2, cv::Size(winSize,winSize));
Mat varMat = t_mean_2 - t_mean.mul(t_mean);
varMat.convertTo(varMat, CV_8U);
// threshold the high variance regions
Mat varMatRegions = varMat > 100;
Bei einem Bild wie diesem:
Wenn ich dann zeige, varMatRegions
bekomme ich dieses Bild:
Wie Sie sehen können, wird der linke Textblock etwas mit der Kopfzeile der Karte kombiniert. Bei den meisten Karten funktioniert diese Methode hervorragend, bei geschäftigeren Karten kann sie jedoch Probleme verursachen.
Der Grund für die Verbindung dieser Konturen ist, dass der Begrenzungsrahmen der Kontur fast die gesamte Karte einnimmt.
Kann jemand einen anderen Weg vorschlagen, wie ich den Text finden kann, um eine ordnungsgemäße Erkennung des Textes zu gewährleisten?
200 Punkte für jeden, der den Text auf der Karte über diesen beiden finden kann.
Antworten:
Sie können Text erkennen, indem Sie Elemente mit engen Kanten finden (inspiriert von einer LPD):
Verwendung:
Ergebnisse:
ein. element = getStructuringElement (cv :: MORPH_RECT, cv :: Size (17, 3));
b. element = getStructuringElement (cv :: MORPH_RECT, cv :: Size (30, 30));
Die Ergebnisse für das andere erwähnte Bild sind ähnlich.
quelle
n
? Danke für die Lösung, es funktioniert super!cv::Rect a;
. Vergrößert um n :a.x-=n/2;a.y-=n/2;a.width+=n;a.height+=n;
.Ich habe im folgenden Programm eine gradientenbasierte Methode verwendet. Die resultierenden Bilder wurden hinzugefügt. Bitte beachten Sie, dass ich für die Verarbeitung eine verkleinerte Version des Bildes verwende.
c ++ Version
Python-Version
quelle
rect
. Es gibt einepyrdown
, also multiplizieren Siex, y, width, height
dierect
mit 4.Hier ist ein alternativer Ansatz, mit dem ich die Textblöcke erkannt habe:
Unten ist der Code, der in Python mit pyopencv geschrieben wurde. Es sollte einfach sein, ihn nach C ++ zu portieren.
Das Originalbild ist das erste Bild in Ihrem Beitrag.
Nach der Vorverarbeitung (Graustufen, Schwellenwert und Dilatation - also nach Schritt 3) sah das Bild folgendermaßen aus:
Unten ist das resultierende Bild ("contoured.jpg" in der letzten Zeile); Die endgültigen Begrenzungsrahmen für die Objekte im Bild sehen folgendermaßen aus:
Sie können sehen, dass der Textblock auf der linken Seite als separater Block erkannt wird, der von seiner Umgebung abgegrenzt ist.
Wenn Sie dasselbe Skript mit denselben Parametern verwenden (mit Ausnahme des Schwellenwerttyps, der für das zweite Bild wie unten beschrieben geändert wurde), sind hier die Ergebnisse für die anderen 2 Karten:
Parameter einstellen
Die Parameter (Schwellenwert, Dilatationsparameter) wurden für dieses Bild und diese Aufgabe (Auffinden von Textblöcken) optimiert und können bei Bedarf für andere Kartenbilder oder andere zu findende Objekttypen angepasst werden.
Für den Schwellenwert (Schritt 2) habe ich einen schwarzen Schwellenwert verwendet. Für Bilder, bei denen der Text heller als der Hintergrund ist, z. B. das zweite Bild in Ihrem Beitrag, sollte ein weißer Schwellenwert verwendet werden. Ersetzen Sie daher den Schwellenwerttyp durch
cv2.THRESH_BINARY
). Für das zweite Bild habe ich auch einen etwas höheren Wert für den Schwellenwert (180) verwendet. Das Variieren der Parameter für den Schwellenwert und die Anzahl der Iterationen für die Dilatation führt zu unterschiedlichen Empfindlichkeitsgraden bei der Abgrenzung von Objekten im Bild.Andere Objekttypen finden:
Wenn Sie beispielsweise die Dilatation im ersten Bild auf 5 Iterationen verringern, werden die Objekte im Bild feiner abgegrenzt, und es werden ungefähr alle Wörter im Bild gefunden (anstatt Textblöcke):
Da ich die grobe Größe eines Wortes kannte, habe ich hier Bereiche verworfen, die zu klein (unter 20 Pixel Breite oder Höhe) oder zu groß (über 100 Pixel Breite oder Höhe) waren, um Objekte zu ignorieren, bei denen es sich wahrscheinlich nicht um Wörter handelt, um die Ergebnisse zu erhalten das obige Bild.
quelle
cv2.findContours
. Es heißtValueError: too many values to unpack
.cv2.findContours
3 Argumente zurückgibt und der ursprüngliche Code nur 2 erfasst.@ dhanushkas Ansatz zeigte sich am vielversprechendsten, aber ich wollte in Python herumspielen, also ging ich voran und übersetzte es zum Spaß:
Nun, um das Bild anzuzeigen:
Nicht das pythonischste Skript, aber ich habe versucht, dem ursprünglichen C ++ - Code so nahe wie möglich zu kommen, damit die Leser ihm folgen können.
Es funktioniert fast so gut wie das Original. Gerne lese ich Vorschläge, wie es verbessert / behoben werden kann, um den ursprünglichen Ergebnissen vollständig zu ähneln.
quelle
drawContours
, für diesen Status. "Die Funktion zeichnet Konturumrisse im Bild, wenn die Dicke> 0 ist, oder füllt den durch die Konturen begrenzten Bereich, wenn die Dicke <0 ist." Dies geschieht, damit wir das Verhältnis von Pixeln ungleich Null überprüfen können, um zu entscheiden, ob das Feld wahrscheinlich Text enthält.Sie können diese Methode ausprobieren , die von Chucai Yi und Yingli Tian entwickelt wurde.
Sie teilen auch eine Software (die auf Opencv-1.0 basiert und unter Windows-Plattform ausgeführt werden sollte), die Sie verwenden können (obwohl kein Quellcode verfügbar ist). Es werden alle Textbegrenzungsrahmen (in Farbschatten dargestellt) im Bild generiert. Wenn Sie sich auf Ihre Beispielbilder anwenden, erhalten Sie die folgenden Ergebnisse:
Hinweis: Um das Ergebnis robuster zu machen, können Sie benachbarte Felder weiter zusammenführen.
Update: Wenn Ihr oberstes Ziel darin besteht, die Texte im Bild zu erkennen, können Sie gttext weiter überprüfen , eine OCR-freie Software und ein Ground Truthing-Tool für Farbbilder mit Text. Quellcode ist ebenfalls verfügbar.
Damit erhalten Sie erkannte Texte wie:
quelle
Über Code JAVA-Version: Danke @William
Und verwenden Sie diesen Code in der Praxis:
quelle
Python-Implementierung für die Lösung von @ dhanushka:
quelle
Dies ist eine C # -Version der Antwort von Dhanushka mit OpenCVSharp
quelle
Dies ist eine VB.NET-Version der Antwort von Dhanushka mit EmguCV .
Einige Funktionen und Strukturen in EmguCV müssen anders berücksichtigt werden als die C # -Version mit OpenCVSharp
quelle