Как я могу использовать tesseract ocr (или любой другой бесплатный ocr) в небольшом проекте c ++? - PullRequest
26 голосов
/ 22 февраля 2011

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

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

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

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

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

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

Ответы [ 4 ]

28 голосов
/ 12 марта 2011

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

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

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

Для начала:

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

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

Вы можете проверить сообщество тессеракта на уже отвеченные вопросы или задать свой здесь .

4 голосов
/ 22 июня 2011

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

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

Любой, я скачал svn из кода Google: http://code.google.com/p/tesseract-ocr/

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

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

  1. Я использовал 'make install', и он поместил некоторые вещи в / usr / include / tesseract
  2. Я скопировал этот каталог в мой домашний каталог
  3. doxygen -g doxygen.conf; # Для создания файла doxygen
  4. Просмотрите файл, который он генерирует, и установите выходной каталог и имя проекта или что-то еще. Я использовал 'doxy-dox' в качестве вывода dir
  5. doxygen -g doxygen.conf
  6. chromium-browser chromium-browser doxy-doc / html / index.html

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

3 голосов
/ 18 сентября 2012

Я понял, что если вы используете Visual Studio 2010 и используете Windows формы / конструктор, вы можете легко добавить этот способ без проблем

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

    ccmain ccstruct ccutil классифицировать куб cutil dict image libtesseract nutral_networks средство просмотра текстаwordrec

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

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

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

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

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

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

  6. Нет необходимости добавлять файлы в ваш проект.только эти строки кода ..... Я включил некоторый дополнительный код, который преобразует из одного набора внешних данных в версию TIFF без необходимости сохранять / загружать файл.Разве я не хорош?

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

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

В моих проектах «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;
    }
}

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

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

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

pps Мне не хочется это говорить, но я внес одно изменение в 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;
2 голосов
/ 06 марта 2011

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

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

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

Удачи!

...