Ich schreibe eine OCR-Anwendung, um Zeichen aus einem Screenshot zu lesen. Momentan konzentriere ich mich nur auf Ziffern. Ich stütze meinen Ansatz teilweise auf diesen Blogpost: Ссылка .
>Ich kann jeden einzelnen Charakter mit einem cleveren Schwellwert erfolgreich extrahieren. Wo es ein bisschen knifflig wird, ist die Übereinstimmung der Charaktere. Auch bei festen Schriftarten und -größen gibt es einige Variablen wie Hintergrundfarbe und Unterschneidung, die dazu führen, dass die gleiche Ziffer in leicht unterschiedlichen Formen erscheint. Zum Beispiel ist das untere Bild in 3 Teile unterteilt:
Die Teile wurden alle skaliert (der Abstand zwischen den beiden grünen horizontalen Linien entspricht einem Pixel).
Sie können sehen, dass trotz der oberen und mittleren Bilder, die eindeutig eine 2 darstellen, der Fehler zwischen ihnen ziemlich hoch ist. Dies führt zu falschen Positiven, wenn andere Ziffern abgeglichen werden. Beispielsweise ist es nicht schwer zu erkennen, wie eine gut platzierte 7 besser mit der Zielziffer im obigen Bild übereinstimmt als das mittlere Bild.
Gegenwärtig gehe ich damit um, indem ich für jede Ziffer einen Haufen Trainingsbilder bereithalte und die Zielziffer mit diesen Bildern übereinstimme, eins nach dem anderen . Ich habe versucht, das durchschnittliche Bild des Trainingssatzes zu nehmen, aber das löst das Problem nicht (falsche Positive auf anderen Ziffern).
Ich bin etwas widerwillig, wenn ich mit einer verschobenen Vorlage übereinstimme (es wäre im Wesentlichen dasselbe wie das, was ich gerade mache). Gibt es eine bessere Möglichkeit, die beiden Bilder zu vergleichen als die einfache absolute Differenz? Ich dachte an etwas wie die EMD (Entfernung der Erde, Ссылка ) in 2D: im Grunde brauche ich eine Vergleichsmethode, die für globale Verschiebungen und kleine lokale Änderungen nicht so empfindlich ist (Pixel neben einem weißen Pixel wird weiß, oder Pixel neben einem schwarzen Pixel werden schwarz), ist aber empfindlich gegenüber globalen Veränderungen (schwarze Pixel, die nicht annähernd weiß sind) Pixel werden schwarz und umgekehrt).
Kann jemand eine effektivere Matching-Methode vorschlagen als den absoluten Unterschied?
Ich mache das alles in OpenCV mit den C-Style-Python-Wrappern ( import cv
).
OCR auf verrauschten Bildern ist nicht einfach - so einfache Ansätze funktionieren nicht gut.
Also würde ich Ihnen empfehlen, HOG zu verwenden, um Features und SVM zu klassifizieren. HOG scheint eine der mächtigsten Möglichkeiten zu sein, Formen zu beschreiben.
Die gesamte Verarbeitungspipeline ist in OpenCV implementiert, jedoch kenne ich die Funktionsnamen in Python-Wrappern nicht. Sie sollten in der Lage sein, mit der neuesten haartraining.cpp zu trainieren - es unterstützt tatsächlich mehr als nur Haar - HOG und LBP auch.
Und ich denke, der neueste Code (aus dem Kofferraum) ist gegenüber der offiziellen Version (2.3.1) sehr verbessert.
HOG benötigt normalerweise nur einen Bruchteil der Trainingsdaten, die von anderen Erkennungsmethoden verwendet werden. Wenn Sie jedoch Formen klassifizieren möchten, die teilweise verschluckt sind (oder fehlen), sollten Sie sicherstellen, dass Sie einige solcher Formen in das Training einbeziehen. p>
Ich kann Ihnen aus meiner Erfahrung und aus der Lektüre mehrerer Artikel zur Zeichenklassifizierung sagen, dass ein guter Einstieg in die Hauptkomponentenanalyse (PCA), Fishers lineare Diskriminanzanalyse (LDA) und Support Vector Machines (SVMs) möglich ist ). Dies sind Klassifikationsmethoden, die für OCR sehr nützlich sind, und es stellt sich heraus, dass OpenCV bereits ausgezeichnete Implementierungen auf PCAs und SVMs . Ich habe keine OpenCV-Codebeispiele für OCR gesehen, aber Sie können eine modifizierte Version der Gesichtsklassifizierung verwenden, um eine Zeichenklassifizierung durchzuführen. Eine ausgezeichnete Quelle für Gesichtserkennungscode für OpenCV ist diese Website .
Eine weitere Bibliothek für Python, die ich Ihnen empfehlen kann, ist "scikits.learn". Es ist sehr einfach, cvArrays an scikits.learn zu senden und maschinelle Lernalgorithmen auf Ihren Daten auszuführen. Ein grundlegendes Beispiel für OCR mit SVM ist hier .
Ein weiteres komplizierteres Beispiel, das vielseitiges Lernen für die Erkennung handgeschriebener Zeichen verwendet, ist hier .
>