Wie kann ich Tesseract OCR (oder ein anderes kostenloses OCR) in einem kleinen C++-Projekt verwenden?

Lesezeit: 12 Minuten

Benutzer-Avatar
Marko29

Was ich nach meiner Recherche gehört habe, ist, dass die einzigen soliden kostenlosen OCR-Optionen beides sind Tesseract oder Keilschrift.

Nun, die Tesseract-Dokumentation ist einfach schrecklich, alles, was sie Ihnen geben, ist ein Haufen Visual Studio-Code (für mich unter Windows) und von da an sind Sie auf sich allein gestellt in einem Ozean ihrer API. Alles, was Sie tun können, ist, die exe zu verwenden, die kompiliert, und sie dann für ein TIFF-Bild zu verwenden.

Ich hatte zumindest eine kurze Dokumentation erwartet, die Ihnen sagt, wie Sie ihren API-Aufruf ziehen können, um OCR zumindest für ein kleines Beispiel zu verwenden, aber nein, es gibt nichts dergleichen in ihren Dokumenten.

CuneiForm: Ich habe es heruntergeladen und “großartig”, alles ist auf Russisch. 🙁

Ist es wirklich schwer für diese Jungs, ein kleines Beispiel zu ziehen, statt sie uns mit einer Menge irrelevanter Informationen zu versorgen, die wahrscheinlich 90% der Leute nicht erreichen werden, wie können Sie dorthin gelangen, ohne mit kleinen Dingen anzufangen, und sie erklären nichts davon!

Ich habe also eine Menge API, aber wie zum Teufel soll ich sie verwenden, wenn sie nirgendwo erklärt wird? … Vielleicht kann mir jemand Rat und eine Lösung anbieten? Ich verlange kein Wunder, nur etwas Kleines, das mir zeigt, wie die Dinge funktionieren.

  • Dies ist eine Beschwerde, die hier nicht geeignet ist. Sie könnten die Beschwerde entfernen, versuchen, entweder tesseract oder cuinform zu verwenden, und mit spezifischeren Problemen zurückkommen. Außerdem bin ich mit keinem der beiden Projekte vertraut, und es würde helfen, wenn Sie zumindest Links bereitstellen würden.

    – David Thornley

    22. Februar 2011 um 15:02 Uhr

  • Willkommen in der Welt der Open-Source-Bibliotheken, wo APIs schlecht sind und nichts dokumentiert wird.

    – Katze Plus Plus

    22. Februar 2011 um 15:09 Uhr

  • @Davi Thornley Ich wünschte, ich könnte es verwenden, aber es ist kein Ausgangspunkt dokumentiert. Ich habe im Internet nach Beispielen gesucht, aber nichts, was ich finden konnte. Meine Frage ist, wo ich anfangen soll, ihre API in mein c-Projekt zu ziehen, nur ein kleines Beispiel, das mich dazu bringen sollte, mehr zu graben, es muss eine Person geben, die eine der beiden in ihrem Projekt verwendet hat

    – Marko29

    22. Februar 2011 um 21:11 Uhr

Sie haben vielleicht aufgegeben, aber es gibt vielleicht noch andere, die es immer noch versuchen. Hier ist also, was Sie brauchen, um mit Tesseract zu beginnen:

Zunächst sollten Sie die gesamte Dokumentation zu Tesseract lesen. Vielleicht finden Sie etwas Nützliches wiki.

Um mit der Verwendung der API (v 3.0.1, derzeit im Trunk) zu beginnen, lesen Sie auch die README- und ChangeLog-Datei von Rüssel) solltest du dir ansehen baseapi.h. Die Dokumentation zur Verwendung der API befindet sich direkt dort, ein Kommentar über jeder Funktion.

Für Starter:

  • enthalten baseapi.h & konstruieren TessBaseAPI Objekt
  • Anruf Init()
  • Einige optional wie
    • Ändern Sie einige Parameter mit der SetVariable() Funk. Sie können alle Parameter und ihre Werte sehen, wenn Sie sie mit in eine Datei drucken PrintVariables() Funk.
    • Ändern Sie den Segmentierungsmodus mit SetPageSegMode(). Teilen Sie tesseract mit, was das Bild darstellt, das Sie mit OCR darstellen möchten – Textblock oder Textzeile, Wort oder Zeichen.
  • SetImage()
  • GetUTF8Text()

(Auch das ist nur der Anfang.)

Sie können in der Community des Tesseract nach bereits beantworteten Fragen suchen oder Ihre eigenen stellen hier.

Ich beschäftige mich damit … bisher habe ich DoxyGen-Code dafür generiert … das hilft. Ich lese aber immer noch alle Dokumente.

Einige Links, die mir weiterhelfen:

Irgendwelche, die ich den SVN von Google Code heruntergeladen habe: http://code.google.com/p/tesseract-ocr/

und erstellte und installierte es dann mit doxygen, um meine eigenen API-Referenzdokumente zu generieren. Sehr hilfreich.

So habe ich es gemacht:

  1. Ich habe ‘make install’ verwendet und es hat einiges in /usr/include/tesseract abgelegt
  2. Ich habe dieses Verzeichnis in mein Heimatverzeichnis kopiert
  3. doxygen -g doxygen.conf; # Um eine Doxygen-Datei zu generieren
  4. Gehen Sie die Datei durch, die es generiert, und legen Sie das Ausgabeverzeichnis und den Projektnamen oder was auch immer fest. Als Ausgabeverzeichnis habe ich ‘doxy-dox’ verwendet
  5. doxygen -g doxygen.conf
  6. Chrom-Browser Chrom-Browser doxy-doc/html/index.html

Hoffe das hilft ein bisschen.

Marko, ich habe versucht, auch eine schnelle C++-App mit Tesseract zu schreiben, und bin auf die gleichen Probleme gestoßen.

Kurz gesagt, ich fand es verwirrend mit kleinen Beispielen / Dokumenten, aber ich bemängele das Produkt nicht, verdammt, es ist Open Source und die Mitwirkenden sind wahrscheinlich mehr daran interessiert, es zu verbessern als am Marketing.

Sie könnten versuchen, im Quellcode herumzustöbern, und möglicherweise etwas Zeit damit verbringen, ein Verständnis zu erlangen, aber ich kann Ihre Frustration voll und ganz nachvollziehen.

Viel Glück!

  • Ich habe es geschafft, es am Ende per Shell-Ausführung zu verwenden, aber es ist so ungenau, dass ich es aufgegeben habe, zumindest bei den Schriftarten, die mich interessierten, und ich kann mir nur vorstellen, wie “Spaß” es macht, es so zu trainieren.

    – Marko29

    10. März 2011 um 3:01 Uhr

  • Ich möchte die Jungs dahinter nicht verprügeln, sondern nur sagen, wie es für mich endete, ich bin sicher, dass es auf seine eigene Weise eine gute Freiheit ist

    – Marko29

    10. März 2011 um 3:02 Uhr

Benutzer-Avatar
Kage_Gaara

Ich habe es herausgefunden, wenn Sie Visual Studios 2010 verwenden und Windows Forms / Designer verwenden, können Sie es auf diese Weise ohne Probleme hinzufügen

  1. Fügen Sie die folgenden Projekte zu Ihrem Projekt hinzu (ich warne Sie einmal, fügen Sie nicht die Tesseract-Lösung hinzu oder ändern Sie keine Einstellungen in den Projekten, die Sie hinzufügen, es sei denn, Sie lieben es, sich selbst zu hassen)

    ccmain ccstruct ccutil classify cube cutil dict image libtesseract nutral_networks textord viewer wordrec

Sie können die anderen hinzufügen, aber Sie möchten nicht wirklich, dass all das in Ihr Projekt eingebaut wird, oder? naaa, bau die separat

  1. Gehen Sie zu Ihren Projekteigenschaften und fügen Sie libtesseract als Referenz hinzu. Jetzt, da es als Projekt sichtbar ist, wird Ihr Projekt schnell erstellt, ohne die Millionen von Warnungen in tesseract zu untersuchen. [common properties]->[add reference]

  2. Klicken Sie im Lösungs-Explorer mit der rechten Maustaste auf Ihr Projekt und klicken Sie auf Projektabhängigkeiten. Stellen Sie sicher, dass es von libtesseract oder sogar allen abhängig ist. Dies bedeutet nur, dass sie vor Ihrem Projekt erstellt werden.

  3. Die Visual Studio-Projekte von Tesseract 2010 enthalten eine Reihe von Konfigurationseinstellungen, auch bekannt als release, release.dll, debug, debug.dll, es scheint, dass die release.dll-Einstellungen die richtigen Dateien erzeugen. Legen Sie zunächst die Lösungsausgabe auf release.dll fest. Klicken Sie auf Ihre Projekteigenschaften. Klicken Sie dann auf Konfigurationsmanager. Wenn dies nicht verfügbar ist, tun Sie dies, klicken Sie auf die Eigenschaften der LÖSUNG in der Lösungsstruktur und klicken Sie auf die Registerkarte Konfiguration, Sie sehen eine Liste der Projekte und die zugehörigen Konfigurationseinstellungen. Sie werden feststellen, dass Ihr Projekt nicht auf release.dll eingestellt ist, obwohl die Ausgabe dies ist. Wenn Sie den zweiten Weg gewählt haben, müssen Sie immer noch auf den Konfigurationsmanager klicken. Dann können Sie die Einstellungen bearbeiten, in Ihren Projekteinstellungen auf Neu klicken und sie release.dll nennen … genau wie die anderen und die Einstellungen aus der Version kopieren. Machen Sie dasselbe für Debug, damit Sie einen debug.dll-Namen haben, der aus den Debug-Einstellungen kopiert wurde. Puh… fast fertig

  4. Versuchen Sie nicht, die Tesseract-Einstellungen so zu ändern, dass sie mit Ihren übereinstimmen … das wird nicht funktionieren … und wenn die neue Version herauskommt, können Sie sie nicht einfach “einwerfen” und loslegen. Akzeptieren Sie die Tatsache, dass Ihre neuen Modi in diesem Zustand Release.dll und Debug.dll sind. Stressen Sie sich nicht … Sie können zurückgehen, wenn es fertig ist, und die Projekte aus Ihrer Lösung entfernen.

  5. Ratet mal, wo die Bibliotheken und DLLs herauskommen? In Ihrem Projekt müssen Sie möglicherweise die Bibliotheksverzeichnisse hinzufügen oder nicht. Einige Leute sagen, dass sie alle Header in einem einzigen Ordner ablegen sollen, damit sie nur einen Ordner zu den Includes hinzufügen müssen, aber ich nicht. Ich möchte in der Lage sein, den Tesseract-Ordner zu löschen und ohne zusätzliche Arbeit aus den Reißverschlüssen neu zu laden … und vollständig bereit sein, in einem Schritt zu aktualisieren oder ihn wiederherzustellen, wenn ich den Code durcheinander gebracht habe. Es ist ein bisschen Arbeit und Sie können es mit Code anstelle der Einstellungen tun, wie ich es mache, aber Sie sollten alle Ordner, die Header-Dateien enthalten, in den 2010-Tesseract-Projektordner aufnehmen und sie in Ruhe lassen.

  6. Sie müssen Ihrem Projekt keine Dateien hinzufügen. nur diese Codezeilen … Ich habe zusätzlichen Code eingefügt, der von einem fremden Datensatz in die tiff-freundliche Version konvertiert, ohne dass eine Datei gespeichert / geladen werden muss. bin ich nicht nett?

  7. Jetzt können Sie in debug.dll und release.dll vollständig debuggen, sobald Sie es erfolgreich in Ihr Projekt eingebaut haben, sogar wenn Sie alle hinzugefügten Projekte entfernen können, und es wird perfekt sein. keine zusätzliche Kompilierung oder Fehler. vollständig debugfähig, ganz natürlich.

  8. Wenn ich mich recht erinnere, kam ich nicht um die Tatsache herum, dass ich die Dateien in 2008/lib/ in meinen Projekt-Release-Ordner kopieren musste…verdammt.

In meinen Projekten habe ich „functions.h“ abgelegt

#pragma comment (lib, "liblept.lib" )
#define _USE_TESSERACT_
#ifdef _USE_TESSERACT_
#pragma comment (lib, "libtesseract.lib" )
#include <baseapi.h>
#endif
#include <allheaders.h>

In meinem Hauptprojekt habe ich dies als Mitglied in eine Klasse eingefügt:

tesseract::TessBaseAPI *readSomeNombers;

und natürlich habe ich irgendwo „functions.h“ eingefügt

dann füge ich das in meinen Klassenkonstruktor ein:

readSomeNombers = new tesseract::TessBaseAPI();
readSomeNombers ->Init(NULL, "eng" );
readSomeNombers ->SetVariable( "tessedit_char_whitelist", "0123456789,." );

Dann habe ich diese Klassenmitgliedsfunktion erstellt: und ein Klassenmitglied, das als Ausgabe dienen soll, nicht hassen, ich mag es nicht, Variablen zurückzugeben. Nicht mein Stil. Der Speicher für die Pix muss nicht zerstört werden, wenn er in einer Mitgliedsfunktion auf diese Weise verwendet wird, glaube ich, und mein Test schlägt vor, dass dies eine sichere Möglichkeit ist, diese Funktionen aufzurufen. Aber auf jeden Fall kannst du alles machen.

void Gaara::scanTheSpot()
{
    Pix *someNewPix;
    char* outText;
    ostringstream tempStream;
    RECT tempRect;
    someNewPix = pixCreate( 200 , 40 , 32 );
    convertEasyBmpToPix( &scanImage, someNewPix, 87, 42 );

    readSomeNombers ->SetImage(someNewPix);
    outText = readSomeNombers ->GetUTF8Text();
    tempStream.str("");
    tempStream << outText;
    classMemeberVariable = tempStream.str();
//pixWrite( "test.bmp", someNewPix, IFF_BMP );
}

Das Objekt mit den Informationen, die ich scannen möchte, befindet sich im Speicher und wird von angezeigt &scanImage. Es stammt aus der „EasyBMP“-Bibliothek, aber das ist nicht wichtig.

Womit ich mich übrigens in einer Funktion in „functions.h“/ „functions.cpp“ befasse, mache ich hier ein wenig zusätzliche Verarbeitung, während ich in der Schleife bin, nämlich die Zeichen auszudünnen und sie schwarz-weiß zu machen und umzukehren Schwarz und Weiß, was unnötig ist. In dieser Phase meiner Entwicklung suche ich noch nach Möglichkeiten, die Erkennung zu verbessern. Für meine Vorschläge hat dies jedoch noch keine schlechten Daten ergeben. Meine Ansicht ist, der Einfachheit halber die Standard-Tess-Daten zu verwenden. Ich gehe heuristisch vor, um ein sehr komplexes Problem zu lösen.

void convertEasyBmpToPix( BMP *sourceImage, PIX *outputImage, unsigned startX, unsigned startY )
{
    int endX = startX + ( pixGetWidth( outputImage ) );
    int endY = startY + ( pixGetHeight( outputImage ) );
    unsigned destinationX;
    unsigned destinationY = 0;
    for( int yLoop = startY; yLoop < endY; yLoop++ )
    {
        destinationX = 0;
        for( int xLoop = startX; xLoop < endX; xLoop++ )
        {
            if( isWhite( &( sourceImage->GetPixel( xLoop, yLoop ) ) ) )
            {
                pixSetRGBPixel( outputImage, destinationX, destinationY, 0,0,0 );
            }
            else
            {
                pixSetRGBPixel( outputImage, destinationX, destinationY, 255,255,255 );
            }
            destinationX++;
        }
        destinationY++;
    }
}
bool isWhite( RGBApixel *image )
{
    if(
        //destination->SetPixel( x, y, source->GetPixel( xLoop, yLoop ) );
        ( image->Red   < 50 ) ||
        ( image->Blue  < 50 ) ||
        ( image->Green < 50 )
        )
    {
        return false;
    }
    else
    {
        return true;
    }
}

Eine Sache, die ich nicht mag, ist die Art und Weise, wie ich die Größe des Bildes außerhalb der Funktion deklariere. Es scheint, wenn ich versuche, es innerhalb der Funktion zu tun, habe ich unerwartete Ergebnisse …. wenn der Speicher zugewiesen wird, während er drin ist, wird er zerstört, wenn ich gehe.

gmail Sicherlich nicht mein elegantestes Werk, aber ich habe es auch der Einfachheit halber ausgehöhlt. Warum ich mir die Mühe mache, das zu teilen, weiß ich nicht. Ich hätte es für mich behalten sollen. Was ist mein Name? Kage.Sabaku.No.Gaara

Bevor ich Sie gehen lasse, sollte ich die feinen Unterschiede zwischen meiner Windows Form App und den Standardeinstellungen erwähnen. Ich verwende nämlich den “Multi-Byte”-Zeichensatz. Projekteigenschaften … und so … einem Hund einen Knochen geben, vielleicht eine Stimme?

pps Ich hasse es zu sagen, aber ich habe eine Änderung an host.c vorgenommen, wenn Sie 64-Bit verwenden, können Sie dasselbe tun. Ansonsten bist du auf dich allein gestellt…..aber mein Grund war ein bisschen verrückt, dass du das nicht musst

typedef unsigned int uinT32;
#if (_MSC_VER >= 1200)            //%%% vkr for VC 6.0
typedef _int64 inT64;
typedef unsigned _int64 uinT64;
#else
typedef long long int inT64;
typedef unsigned long long int uinT64;
#endif                           //%%% vkr for VC 6.0
typedef float FLOAT32;
typedef double FLOAT64;
typedef unsigned char BOOL8;

Wenn Sie Windows 10 verwenden, gibt es die OCR-API. es muss nichts installiert werden.

Das Zeug ist sehr schwer, es richtig zu machen. die Dokumentation war sehr nicht einfach zu handhaben.

Aber ich habe es richtig verstanden.

Hier ist eine einfache Funktion, die die OCR-Engine-API von Windows 10 verwendet:


// For the Windows 10 OCR API
#include "winrt/Windows.Storage.Streams.h"
#include "winrt/Windows.Graphics.Imaging.h"
#include "winrt/Windows.Media.Ocr.h"
#include "winrt/Windows.Networking.Sockets.h"
#include "winrt/Windows.Globalization.h"
#pragma comment(lib, "pathcch")
#pragma comment(lib,"windowsapp.lib")

std::string ExtractTextFromImage(byte* pixels, int xSize, int ySize)
{
    using namespace winrt;

    Windows::Globalization::Language lang = Windows::Globalization::Language(L"en");
    Windows::Media::Ocr::OcrEngine engine = Windows::Media::Ocr::OcrEngine::TryCreateFromLanguage(lang);
    //OcrEngine engine = OcrEngine::TryCreateFromUserProfileLanguages();


    int pixels_size = xSize * ySize * 4;

    Windows::Storage::Streams::InMemoryRandomAccessStream stream = { 0 };
    Windows::Storage::Streams::DataWriter writer(stream);


    array_view<const byte> bytes(pixels, pixels + pixels_size);

    writer.WriteBytes(winrt::array_view<const byte>(bytes));

    Windows::Storage::Streams::IBuffer buffer = writer.DetachBuffer();



    Windows::Graphics::Imaging::SoftwareBitmap bitmap = Windows::Graphics::Imaging::SoftwareBitmap::CreateCopyFromBuffer
    (
        buffer,
        Windows::Graphics::Imaging::BitmapPixelFormat::Bgra8,
        xSize,
        ySize
    );

    Windows::Media::Ocr::OcrResult result = engine.RecognizeAsync(bitmap).get();
    std::string output = winrt::to_string(result.Text());

    bitmap.Close();
    writer.Close();



    return output;
}


1367830cookie-checkWie kann ich Tesseract OCR (oder ein anderes kostenloses OCR) in einem kleinen C++-Projekt verwenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy