2015-08-05 3 views
2

Мы используем php, pypdfocr и pdftotext для OCR и извлекаем текст из документов, которые были отсканированы или отправлены по факсу нам. Вопрос в том, когда документ сканируется или по факсу с ног на голову, или если некоторые страницы предназначены для чтения ландшафта (так что текст поворачивается на 90 градусов на странице)обнаруживает pdf-страницы, которые перевернуты

вещи я пытался:

  • в tessdata ф eng.traineddata osd.traineddata

в результате OCR слой текста для страниц, которые имеют 90 градусов текст не плохо, однако страницы, которые с ног на голову, это OCR-х каждое слово и переворачивает его на месте, так что если «Это тест» появляется в документе, но с ног на голову текстовый слой может читать «test a is This»

Если есть способ обнаружить, что страница перевернута, я могу использовать pdftk для поворота страниц, прежде чем запускать ее через OCR (или я смогу удалить текстовый слой, если он был OCR'd, и запустить его, хотя OCR снова после использования pdftk для поворота)

Любое решение, которое может быть выполнено из CLI linux в этом месте, является жизнеспособным решением.

ответ

4

Вы можете легко получить информацию о ориентации страницы с помощью tesseract (> = 3.03?). Например.

$ tesseract image.png - -psm 0 

будет производить этот вывод

Orientation: 3 
Orientation in degrees: 90 
Orientation confidence: 25.40 
Script: 1 
Script confidence: 18.40 

Основываясь на этой информации, вы можете регулировать поворот изображения. Пример, как это сделать в python, может быть, например, по сценарию Fix image rotation with tesseract.

+0

Спасибо, с этим я могу написать сценарий для автоматического процесса дия (вращение затруднительного и OCR) После того, как я его закончил, я отправлю его обратно сюда в случае полезно кому-либо в будущее. – Logikos

1

У меня была эта проблема. Мое исправление заключалось в создании простого приложения на C++, которое принимает имя файла PNG в качестве параметра и автоматически поворачивает/конструирует его.

Мой код

#include <iostream> 
#include <cmath> 
#include <tesseract/baseapi.h> 
#include <leptonica/allheaders.h> 

using namespace std; 

int main(int argc, char **argv) 
{ 

    if (argc != 2) { 
     cerr << "usage: " << argv[0] << " <image>\n"; 
     exit(1); 
    } 

    tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI(); 
    // Initialize tesseract-ocr with English, without specifying tessdata path 
    if (api->Init(NULL, "eng")) { 
     cerr << "Could not initialize tesseract.\n"; 
     exit(2); 
    } 

    const char* inputfile = argv[1]; 
    tesseract::Orientation orientation; 
    tesseract::WritingDirection direction; 
    tesseract::TextlineOrder order; 
    float deskew_angle; 

    PIX *image = pixRead(inputfile); 
    if (image == NULL) { 
     cerr << "could not open " << inputfile << endl; 
     return -2; 
    } 

    api->SetPageSegMode(tesseract::PSM_AUTO_OSD); 
    api->SetImage(image); 
    api->Recognize(0); 

    tesseract::PageIterator* it = api->AnalyseLayout(); 
    it->Orientation(&orientation, &direction, &order, &deskew_angle); 
    cout << "Orientation: " << orientation << 
      "\nWritingDirection: " << direction << 
      "\nTextlineOrder: " << order << 
      "\nDeskew angle: " << deskew_angle << "\n"; 

    PIX* pixd = NULL; 
    switch (orientation) { 
     case 0: 
      cout << "image in the correct position, nothing to do\n"; 
      if (fabs(deskew_angle) > 0.0001f) { 
       cout << "deskewing...\n"; 
       pixd = pixRotate(image, -deskew_angle, L_ROTATE_SHEAR, L_BRING_IN_WHITE, 0, 0); 
      } 
      break; 
     case 1: 
      cout << "rotating image by 270 degrees\n"; 
      pixd = pixRotate90(image, -1); 
      if (deskew_angle > 0.0001f) { 
       cout << "deskewing...\n"; 
       pixd = pixRotate(pixd, -deskew_angle, L_ROTATE_SHEAR, L_BRING_IN_WHITE, 0, 0); 
      } 
      break; 
     case 2: 
      cout << "rotating image by 180 degrees\n"; 
      pixd = pixRotate180(NULL, image); 
      if (deskew_angle > 0.0001f) { 
       cout << "deskewing...\n"; 
       pixd = pixRotate(pixd, -deskew_angle, L_ROTATE_SHEAR, L_BRING_IN_WHITE, 0, 0); 
      } 
      break; 
     case 3: 
      cout << "rotating image by 90 degrees\n"; 
      pixd = pixRotate90(image, 1); 
      if (deskew_angle > 0.0001f) { 
       cout << "deskewing...\n"; 
       pixd = pixRotate(pixd, -deskew_angle, L_ROTATE_SHEAR, L_BRING_IN_WHITE, 0, 0); 
      } 
      break; 
    } 

    pixDestroy(&image); 

    if (pixd != NULL) { 
     pixWrite(inputfile, pixd, IFF_PNG); 
     pixDestroy(&pixd); 
    } 

    return 0; 
} 

Вы можете скомпилировать его с

g++ -o tesseract_fixposition tesseract_fixposition.cpp -llept -ltesseract 

Зависимости libtesseract и libleptonica. Я тестировал Tesseract версии 3.03 и 3.04 и Leptonica 1.72. Я обработал несколько тысяч изображений и не нашел неправильной идентификации.

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

+0

Nice. То, что я на самом деле имею в виду, это PDF, хотя я написал сценарий в php, который петли, хотя страницы pdf, он запускает команду командной оболочки для преобразования каждой страницы в png, затем я выполняю tesseract на странице png и проанализируйте вывод, строя строку, когда я иду, хотя цикл перейдет к pdftk. Это работает отлично, но для фиксации вращения потребовалось 4 минуты, а затем OCR заключительный документ. Идея выполненного приложения C++ кажется хорошей идеей, так как это, скорее всего, ускорит процесс.Насколько сложно было бы изменить этот скрипт, чтобы исправить каждую страницу pdf? – Logikos

+0

В моем случае это занимает несколько секунд на странице. Я использую это приложение в рабочем процессе, который извлекает каждую страницу с помощью muPDF, готовит ее для извлечения и запускает Tesseract для извлечения. Я использую 'mudraw -r 300 -g -o ' для каждой страницы, а затем это приложение для сгенерированных PNG. – gxrmr

1

Если скорость выдается, вы не используете tesseract для фиксации ориентации страницы. Вы можете использовать только функции лептоники. Что-то вроде этого:

/* 
* Compile with: 
*  g++ fixorientation.cpp -o fixorientation -llept 
* 
*/ 

#include <cstring> 
#include <leptonica/allheaders.h> 

int main(int argc, char *argv[]) { 
    const char* filename = NULL; 
    const char* outfile = NULL; 
    l_int32 orient, format; 
    l_int32 alt_rot = -1; 
    l_float32 upconf1, leftconf1; 
    PIX  *fpixs, *pixs; 

    if (argc < 1) { 
     fprintf(stderr, "Usage is:\n\t%s -f filename [-o output]\n", argv[0]); 
     return(1); 
    } else { 
     for (int i = 1; i < argc; i++) { 
      if (i + 1 < argc) { 
       if (strcmp(argv[i], "-f") == 0) { 
        filename = argv[i + 1]; 
       } else if (strcmp(argv[i], "-o") == 0) { 
        outfile = argv[i + 1]; 
       } 
      } 
     } 
    } 

    if (filename) { 
     pixs = pixRead(filename); 
    } else { 
     fprintf(stderr, "Usage is:\n\t%s -f filename [-o output]\n", argv[0]); 
     return(1); 
    } 

    if (pixs == NULL) { 
     fprintf(stderr, "Unsupported image type.\n"); 
     return(3); 
    } 
    format = pixGetInputFormat(pixs); 

    fpixs = pixConvertTo1(pixs, 130); 
    pixOrientDetect(fpixs, &upconf1, &leftconf1, 0, 0); 
    makeOrientDecision(upconf1, leftconf1, 0, 0, &orient, 1); 

    if (orient == L_TEXT_ORIENT_UNKNOWN) { 
     fprintf(stdout, "Confidence is low; no determination is made. " 
       "But maybe there is %1 deg rotation.\n", alt_rot); 
    } else if (orient == L_TEXT_ORIENT_UP) { 
     fprintf(stdout, "Text is rightside-up\n"); 
     alt_rot = 0; 
    } else if (orient == L_TEXT_ORIENT_LEFT) { 
     fprintf(stdout, "Text is rotated 90 deg ccw\n"); 
     alt_rot = 1; 
    } else if (orient == L_TEXT_ORIENT_DOWN) { 
     fprintf(stdout, "Text is upside-down\n"); 
     alt_rot = 2; 
    } else { /* orient == L_TEXT_ORIENT_RIGHT */ 
     fprintf(stdout, "Text is rotated 90 deg cw\n"); 
     alt_rot = 3; 
    } 

    if (alt_rot > -1) { 
     fpixs = pixRotateOrth(pixs, alt_rot); 
     if (outfile) { 
      pixWrite(outfile, fpixs, format); 
     } else { 
      char savefile[strlen("fixed_") + strlen(filename) + 1]; 
      strcpy(savefile, "fixed_"); 
      strcat(savefile, filename); 
      fprintf(stdout, "Output save to %s\n", savefile); 
      pixWrite(savefile, fpixs, format); 

     } 
    } else { 
     return(2); 
    } 
    pixDestroy(&fpixs); 
    pixDestroy(&pixs); 
    return(0); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^