Подтвердить что ты не робот

Как я могу использовать tesseract ocr (или любой другой свободный ocr) в небольшом проекте С++?

Итак, что я услышал после исследования, так это то, что единственными вариантами OCR являются либо Tesseract, либо CuneiForm.

Теперь документы Tesseract просто ужасны, все, что они вам дают, это набор кода Visual Studio (для меня в Windows), и оттуда вы сами по себе в океане их API. Все, что вы можете сделать, это использовать exe, который компилирует, а затем использовать его на образе TIFF.

Я ожидал, по крайней мере, короткую документацию, которая расскажет вам, как заставить их API-вызов использовать OCR хотя бы для небольшого примера, но нет, в их документах нет ничего подобного.

CuneiForm: я его скачал и "отлично" все по русски.: (

Неужели этим парням трудно привести небольшой пример, вместо этого они предоставляют нам кучу не относящейся к делу информации, которую, вероятно, не получат 90% людей, как вы можете туда добраться, не начиная с мелочей, и они ничего не объясняют!

Так что у меня есть куча API, но как, черт возьми, я должен его использовать, если он нигде не объясняется?... Может быть, кто-то может предложить мне совет и решение? Я не прошу чуда, просто что-то маленькое, чтобы показать мне, как все работает.

4b9b3361

Ответ 1

Возможно, вы отказались, но могут быть и другие, которые все еще пытаются. Итак, вот что вам нужно начинать с tesseract:

Прежде всего, вы должны прочитать всю документацию о tesseract. Вы можете найти что-то полезное wiki.

Чтобы начать использовать API (v 3.0.1, в настоящее время в багажнике, прочитайте также README и ChangeLog из trunk), вы должны проверьте baseapi.h. Документация о том, как использовать api, есть прямо там, комментарий выше каждой функции.

Для начала:

  • включить baseapi.h и построить объект TessBaseAPI
  • вызов Init()
  • Некоторые дополнительные функции
    • измените некоторые параметры с помощью функции SetVariable(). Вы можете увидеть все параметры и их значения, если вы напечатаете их в файле с помощью PrintVariables() func.
    • измените режим сегментации на SetPageSegMode(). Сообщите tesseract, что представляет собой изображение, которое вы собираетесь использовать для OCR - блок или строка текста, слова или символа.
  • SetImage()
  • GetUTF8Text()

(Опять же, это только для начинающих.)

Вы можете проверить сообщество tesseract на вопросы alredy answerd или задать здесь.

Ответ 2

Я копаю в нем. Пока я создал код DoxyGen для него.. это помогает. Все еще читаю все документы.

Некоторые ссылки, которые помогают мне:

Я загрузил svn из кода google: http://code.google.com/p/tesseract-ocr/

а затем его и установили, а затем использовали doxygen для создания моих собственных справочных документов API. Очень полезно.

Как я это сделал:

  • Я использовал 'make install', и он добавил некоторые вещи в /usr/include/tesseract
  • Я скопировал этот каталог в мой домашний каталог
  • doxygen -g doxygen.conf; # Чтобы создать файл doxygen
  • Пройдите через созданный файл и установите выходной каталог dir и project или что угодно. Я использовал "doxy-dox" в качестве моего выходного dir
  • doxygen -g doxygen.conf
  • хром-браузер с хромовым браузером doxy-doc/html/index.html

Надеюсь, что это поможет.

Ответ 3

Я понял, что если вы используете визуальные студии 2010 года и используете windows forms/designer, вы можете легко добавить этот способ без проблем.

  • добавить в проект следующие проекты (я предупреждаю вас один раз, не добавляйте решение tesseract или не изменяйте какие-либо настройки в добавляемых проектах, если вы не любите ненавидеть себя)

    ccmain ccstruct ccutil классифицировать куб cutil ДИКТ образ libtesseract nutral_networks textord зритель wordrec

вы можете добавить других, но вы действительно не хотите, чтобы все, что было встроено в ваш проект, не так ли? naaa, постройте их отдельно

  • перейдите к свойствам вашего проекта и добавьте libtesseract в качестве ссылки, теперь вы можете видеть, что это видно как проект, и это сделает так, чтобы ваш проект быстро строился, не изучая миллионы предупреждений в tesseract. [общие свойства] → [добавить ссылку]

  • щелкните правой кнопкой мыши свой проект в обозревателе решений и выберите зависимости проекта, убедитесь, что он зависит от libtesseract или даже всех из них, это просто означает, что они строят перед вашим проектом.

  • Проекты визуальной студии tesseract 2010 содержат ряд настроек конфигурации, таких как release, release.dll, debug, debug.dll, кажется, что параметры release.dll создают нужные файлы. Сначала установите выход решения в release.dll. Выберите свойства проекта. Затем щелкните диспетчер конфигурации. Если это не доступно, сделайте это, щелкните свойства SOLUTION в дереве решений и щелкните вкладку конфигурации, вы увидите список проектов и соответствующие параметры конфигурации. Вы заметите, что ваш проект не настроен на release.dll, даже если он есть. Если вы заняли второй маршрут, вам все равно нужно нажать диспетчер конфигурации. Затем вы можете отредактировать настройки, щелкнуть новое в настройках своих проектов и вызвать его release.dll... точно так же, как и остальные, и скопировать настройки из выпуска. Сделайте то же самое для Debug, чтобы у вас было имя debug.dll, скопированное из настроек отладки. колесо... почти сделано

  • Не пытайтесь изменить настройки tesseracts в соответствии с вашими... это не будет работать... и когда выйдет новый релиз, вы не сможете просто "бросить его" и уйти. Примите тот факт, что в этом состоянии ваши новые режимы - Release.dll и Debug.dll. не стресс... вы можете вернуться, когда его закончить, и удалить проекты из вашего решения.

  • Угадайте, где выйдут библиотеки и библиотеки DLL? в вашем проекте вам может потребоваться или не нужно добавлять каталоги библиотек. Некоторые люди говорят, что нужно сбрасывать все заголовки в одну папку, поэтому им нужно добавить только одну папку для входящих, но не меня. Я хочу, чтобы иметь возможность удалять папку tesseract и перезагружать ее из ZIP файлов без дополнительной работы... и быть полностью готовым к обновлению за один шаг или восстановить его, если я испорчу код. Это небольшая работа, и вы можете с ней использовать код вместо настроек, которые я делаю, но вы должны включить все папки, содержащие файлы заголовков в папке проекта tesseract 2010, и оставить их в покое.

  • нет необходимости добавлять файлы в проект. просто эти строки кода..... Я включил некоторый дополнительный код, который преобразует из одного иностранного набора данных в дружественную версию tiff, без необходимости сохранять/загружать файл. arent я nice?

  • теперь вы можете полностью отлаживать файлы debug.dll и release.dll, как только вы успешно вложили его в свой проект даже после того, как сможете удалить все добавленные проекты, и это будет неудобно. нет дополнительной компиляции или ошибок. полностью отлаживаемый, все естественный.

  • Если я правильно помню, я не мог обойти тот факт, что мне пришлось копировать файлы в 2008/lib/в папку выпуска моих проектов....darn.

В моих проектах "functions.h" я помещаю

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

в моем основном проекте я помещаю это в класс как член:

tesseract::TessBaseAPI *readSomeNombers;

и, конечно, я включил "functions.h" где-то

то я поместил это в свой конструктор классов:

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

то я создал эту функцию-член класса: и член класса для вывода в качестве вывода, не ненавижу, мне не нравятся возвращаемые переменные. Не мой стиль. Память для пикса не нужно уничтожать при использовании внутри функции-члена таким образом, я считаю, и мой тест показывает, что это безопасный способ вызова этих функций. Но, во что бы то ни стало, вы можете делать все.

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 );
}

Объект, который имеет информацию, которую я хочу сканировать, находится в памяти и на него указывает &scanImage. Это из библиотеки "EasyBMP", но это не важно.

Что я рассматриваю в функции в "functions.h" / "functions.cpp" Кстати, я делаю небольшую дополнительную обработку здесь, пока я нахожусь в цикле, а именно истончение персонажей и превращение его в черно-белое и обратное черное и белое, что не нужно. На этом этапе моего развития я все еще ищу способы улучшить признание. Хотя для моих предложений это еще не дало плохих данных. Мое мнение состоит в том, чтобы использовать данные Tess по умолчанию для простоты. Я действую эвристически, чтобы решить очень сложную проблему.

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;
    }
}

мне не нравится то, как я объявляю размер пикселя вне функции. Кажется, если я попытаюсь сделать это внутри функции, у меня появятся неожиданные результаты.... если выделена память, а внутри она уничтожается, когда я ухожу.

g m a я l Конечно, не моя самая элегантная работа, но я просто избавился от нее из-за простоты. Почему я не разделяю это, я не знаю. Я должен был держать это в себе. Как меня зовут? Kage.Sabaku.No.Gaara

Прежде чем я отпущу вас, я должен упомянуть тонкие различия между моим окном и приложениями по умолчанию. а именно, я использую "многобайтовый" набор символов. свойства проекта... и такие.. дать собаке кость, возможно, голосование?

p.p.s. Мне не нравится это говорить, но я сделал одно изменение на host.c, если вы используете 64 бит, вы можете сделать то же самое. В противном случае ваш по своему усмотрению..... но мой разум был немного сумасшедшим, вам не нужно

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;

Ответ 4

Марко, я попытался написать быстрое приложение на С++, используя Tesseract, и столкнулся с теми же проблемами.

В двух словах я нашел это путающим с небольшими примерами/документами, но я не ошибаюсь в продукте, черт возьми, это с открытым исходным кодом, и вкладчики, вероятно, больше заинтересованы в его улучшении, чем в маркетинге.

Вы могли бы попытаться заглянуть в исходный код и, возможно, потратить время на понимание, но я могу полностью связать ваше разочарование.

Удачи!

Ответ 5

Если вы используете Windows 10, есть OCR API. не нужно ничего устанавливать.

Материал очень трудно понять правильно. с документацией работать было очень непросто.

Но я правильно понял.

Вот простая функция, которая использует API механизма распознавания Windows 10:


// 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;
}