TesseractOCR Sprachen auflisten

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von tron25.

    TesseractOCR Sprachen auflisten

    Hallo

    ich möchte eine Ausklappliste mit den vorhandenen Sprachen füllen. Ich benutze TesseractOCR. In dem Unterordner "tessdata" befinden sich zur Zeit die beiden Dateien für Deutsch und Englisch. Ich möchte also die verfügbaren Sprachen von TesseractOCR durchgehen und die in die Ausklappliste aufnehmen, zu denen auch die entsprechenden Dateien vorhanden sind. Leider gibt es aber das Problem, dass ich bei jedem Schleifendurchgang "unknown" zurückbekomme. Hier mein Code:

    VB.NET-Quellcode

    1. OCRSpracheCombo.Items.Clear()
    2. dim OCRSprachenliste as New List(Of String)
    3. dim OCRDateiname as String
    4. OCRSprachenliste = [Enum].GetNames(GetType(Language)).ToList
    5. For Each Sprache As String In OCRSprachenliste
    6. OCRDateiname = Enums.LanguageHelper.StringToEnum(Sprache).ToString
    7. OCRDateiname &= ".traineddata"
    8. If My.Computer.FileSystem.FileExists(Userverzeichnis & "\tessdata\" & OCRDateiname) Then
    9. For x As Integer = 1 To Sprache.Length - 1
    10. If Sprache.Substring(x, 1) = Sprache.Substring(x, 1).ToUpper Then
    11. Sprache = Sprache.Substring(0, x) & " " & Sprache.Substring(x, Sprache.Length - 1)
    12. End If
    13. Next
    14. OCRSpracheCombo.Items.Add(Sprache)
    15. End If
    16. Next

    Hat jemand von euch Erfahrung mit TesseractOCR oder sogar eine Idee?

    Vielen Dank!
    @tron25 Was steht in dem Enum Language?
    Was steht in OCRDateiname?
    Kann es sein, dass Du "Deutsch" reingibst, die DLL aber "DE-de" oder "DE" haben will?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    OCRDateiname ist ein String in dem zuerst der Wert des entsprechenden Enums eingetragen werden soll. Danach wird die Endung drangehängt und danach gesucht, ob es diese Datei gibt.

    Wenn man beispielsweise statt "Sprache" "Enums.Language.German" eingibt, funktioniert es. Ich weiß nicht, wie ich diesen Wert erhalten kann.
    Welche Sprach-Dateien sind denn vorhanden?
    Und:
    Mach Dir ein Dictionary(Of DEIN_ENUM, Dateiname).
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Was steht in OCRDateiname?

    tron25 schrieb:

    OCRDateiname ist ein String in dem zuerst der Wert des entsprechenden Enums eingetragen werden soll.
    Das beantwortet nicht die Frage. Was steht tatsächlich während der Codeausführung in der Variable drin, ist die Frage. Und wenn dieser Wert plus ".traineddata" eben keinen existierenden Dateinamen angibt, schmilzt das Problem auf diesen Punkt zusammen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    In OCDateiname steht "". Später wird abgefragt, ob diese Datei vorhanden ist. Bei ".traineddata" kommt "False" heraus.
    TesseractOCR bietet u.a. die Funktionen "EnumToString" und "StringToEnum" an. Daraufhin habe ich nun folgenden Code zusammengeschußtert:

    VB.NET-Quellcode

    1. Dim OCRSprachenliste As Array
    2. OCRSprachenliste = [Enum].GetNames(GetType(Language)).ToArray
    3. For Each Sprache As String In OCRSprachenliste
    4. 'In der folgenden Zeile kommt die folgende Fehlermeldung:
    5. 'Der Wert vom Typ "String" kann nicht in "Language" konvertiert werden
    6. Dim S As Enums.Language = DirectCast(Sprache, Enums.Language)
    7. OCRDateiname = Enums.LanguageHelper.EnumToString(S)
    8. OCRDateiname &= ".traineddata"
    9. If My.Computer.FileSystem.FileExists(Userverzeichnis & "\tessdata\" & OCRDateiname) Then
    10. For x As Integer = 1 To Sprache.Length - 1
    11. If Sprache.Substring(x, 1) = Sprache.Substring(x, 1).ToUpper Then
    12. Sprache = Sprache.Substring(0, x) & " " & Sprache.Substring(x, Sprache.Length - 1)
    13. End If
    14. Next
    15. OCRSpracheCombo.Items.Add(Sprache)
    16. End If
    17. Next

    Kann jemand meine Verständnislücke füllen?
    Die Idee mit der Datei, in der die zur Verfügung stehenden Sprachen stehen, hatte ich auch schon, aber ich möchte, dass das System selbständig anhand der vorhandenen Dateinamen die vorhandenen Sprachen erkennt.

    tron25 schrieb:

    Bei ".traineddata" kommt "False" heraus.
    Ich nehme mal an, Du meinst bei FileExists.
    Packe den kompletten Pfad in eine separate Variable und sieh Dir deren Inhalt an.
    Gibt es diese Datei?
    Lerne zu debuggen!
    Debuggen, Fehler finden und beseitigen
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    VB.NET-Quellcode

    1. OCRDateiname &= ".traineddata"
    2. Dim V As String = Userverzeichnis & "\tessdata\" & OCRDateiname

    In V steht:
    C:\Users\Tron\Documents\PunktBilder\tessdata\.traineddata
    Es funktioniert so, wie es funktionieren soll.
    Allerdings ist die "FileExists"-Abfrage nicht das Problem, sondern, wie ich einen String in ein Language umwandeln kann und dessen Enum-Wert herausbekomme.
    Ich dachte, dass ich aus dem Array, in das ich das Enum.Language schreiben lasse, den Wert herausbekommen kann. Beispielsweise bei der Sprache "German" den Wert "deu". Leider funktioniert das auch nicht.
    Ich werde mal eine kleine Anwendung schreiben und hier posten.
    @tron25 Ein Enum ist auch nur ein Integer, wenn das überhaupt so ein Enum ist..
    Ersetze in der Deklaration der betreffenden Prozedur das EnumX durch Integer und rufe die Prozedur mit 0, 1, 2 auf.
    Feddich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hi

    Irgendwie muss Dir doch Deine OCR sagen können, welche Sprachen vorhanden sind und wenn ja, in welcher Form? Als deu oder als de-DE für Deutsch? en, eng oder en-US für Englisch?
    Mfg -Franky-

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „-Franky-“ ()

    Ja, wenn man "Enums.Language." schreibt, öffnet sich ein Fenster mit allen Sprachen. Beispielsweise "Enums.Language.German". Für diesen Eintrag wird die Datei "deu.trainneddata" im Ordner "tessdata" benötigt.

    Ich habe folgende kleine Anwendung erstellt, die mein Problem veranschaulichen soll. Vielleicht hilft das ja ein wenig. Da die Anwendung zum Hochladen zu groß ist, mußte ich einerseits den Inhalt von Packages entfernen und andererseits im Ausführungsordner im Verzeichnis "tessdata" zwei Dummy-Dateien ohne Inhalt erstellen. Wenn das Projekt in Visual Studio geöffnet ist, sollte man im Menü "Projekt" auf "Nuget-Pakete verwalten" gehen und auf der Registerkarte "Aktualisierungen" den Schalter "Wiederherstellen" anklicken, damit die benötigten Pakete wieder hinzugefügt werden.
    Dateien
    • Tesseract OCR.zip

      (49,68 kB, 31 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „tron25“ ()

    Wenn man davon absieht, dass das nicht kompiliert, weil in der Zeile

    VB.NET-Quellcode

    1. Dim S As Enums.Language = DirectCast(Sprache, Enums.Language)
    ein String nicht in ein Language-EnumWert konvertiert werden kann, versuchst Du irgendwie Sprachbezeichnungen in andere Ausdrücke zu wandeln. Aus Deutsch willst Du deu machen. Dieses deu brauchst Du, um den Dateipfad vollständig erstellen zu können, weil die Datei deu.tessdata heißt.
    Ein Blick in den metacode von Language gibt Dir den Weg an: jeder SprachEnumWert hat ein Attribut, welches wohl auch als Dateiname verwendet wird.

    ##########

    Damit solltest Du was anfangen können:

    VB.NET-Quellcode

    1. For Each LanguageValue In GetValues(GetType(Language)).Cast(Of Language)
    2. Dim OCRDateiname = LanguageHelper.EnumToString(LanguageValue)
    3. Dim Sprachbezeichnung = GetName(GetType(Language), LanguageValue)
    4. Next

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Danke. Es funktioniert jetzt. Der Code sieht jetzt so aus:

    VB.NET-Quellcode

    1. OCRSpracheCombo.Items.Clear()
    2. OCRSpracheCombo.Items.Add(My.Resources.Keine)
    3. For Each Sprachenwert In GetValues(GetType(Language)).Cast(Of Language)
    4. OCRDateiname = LanguageHelper.EnumToString(Sprachenwert)
    5. OCRDateiname &= ".traineddata"
    6. AktuelleSprache = GetName(GetType(Language), Sprachenwert)
    7. If My.Computer.FileSystem.FileExists(Programmverzeichnis & "\tessdata\" & OCRDateiname) Then
    8. For x As Integer = 1 To AktuelleSprache.Length - 1
    9. If AktuelleSprache.Substring(x, 1) = AktuelleSprache.Substring(x, 1).ToUpper Then
    10. AktuelleSprache = AktuelleSprache.Substring(0, x) & " " & AktuelleSprache.Substring(x, AktuelleSprache.Length - 1)
    11. End If
    12. Next
    13. OCRSpracheCombo.Items.Add(AktuelleSprache)
    14. End If
    15. Next

    Hierbei werden auch nötige Leerzeichen eingefügt.
    Jetzt habe ich noch ein Problem. Mit der folgenden Zeile wird die Texterkennung gestartet:

    VB.NET-Quellcode

    1. Dim OCR As New TesseractOCR.Engine("tessdata", Enums.Language.German, Enums.EngineMode.TesseractAndLstm)

    Wie kann ich aus dem String "German" den ENUM-Wert "Enums.Language.German" bekommen?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „tron25“ ()

    Das sollte eigentlich schon aufgrund des bestehenden Codes klar sein.

    VB.NET-Quellcode

    1. Dim DerEnumWertFürGerman = GetValues(GetType(Language)).Cast(Of Language).Single(Function(x) GetName(GetType(Language), x) = "German")
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Danke, aber ich habe es jetzt folgendermaßen gelöst:

    VB.NET-Quellcode

    1. Dim OCRDateiname As String = ""
    2. Dim AktuelleSprache As String = ""
    3. Dim Gefunden As Boolean = False
    4. Dim OCRAktuelleSprache As Enums.Language
    5. For Each Sprachenwert In GetValues(GetType(Language)).Cast(Of Language)
    6. AktuelleSprache = GetName(GetType(Language), Sprachenwert)
    7. 'Nun wird die aktuelle Sprache mit der Voreingestellten verglichen.
    8. 'Dabei müssen aus der Voreingestellten alle leerzeichen entfernt werden.
    9. If OCRSprache.Replace(" ", "").ToUpper = AktuelleSprache.ToUpper Then
    10. OCRAktuelleSprache = Sprachenwert
    11. OCRDateiname = LanguageHelper.EnumToString(Sprachenwert)
    12. OCRDateiname &= ".traineddata"
    13. If My.Computer.FileSystem.FileExists(Userverzeichnis & "\tessdata\" & OCRDateiname) Then
    14. Gefunden = True
    15. Exit For
    16. End If
    17. End If
    18. Next
    19. If Gefunden Then
    20. Dim OCR As New TesseractOCR.Engine(Userverzeichnis & "\tessdata", OCRAktuelleSprache, Enums.EngineMode.Default)
    21. Dim OCRBild = TesseractOCR.Pix.Image.LoadFromFile(Userverzeichnis & "\TempOCR.png")
    22. Dim OCRSeite = OCR.Process(OCRBild)
    23. For Each Spalte In OCRSeite.Layout
    24. AktuelleZeile &= Spalte.ToString & vbNewLine & vbNewLine
    25. Next
    26. AktuelleZeile = OCRSeite.Text
    27. AktuelleZeile = AktuelleZeile.Replace(vbLf, vbCrLf)
    28. End If