обнаружить PDF-страницы, которые перевернуты

Мы используем php, pypdfocr и pdftotext для распознавания текста и извлекаем текст из документов, которые были отсканированы или отправлены нам по факсу. Проблема заключается в том, что документ сканируется или пересылается по факсу вверх ногами или если некоторые страницы предназначены для чтения в альбомной ориентации (поэтому текст на странице поворачивается на 90 градусов)

Вещи, которые я пробовал:

  • в tessdata cp eng.traineddata osd.traineddata

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

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

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

2

Решение

Вы можете легко получить информацию об ориентации страницы с помощью 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, может быть, например. по сценарию Исправить поворот изображения с помощью tesseract.

4

Другие решения

У меня была такая же проблема. Мое исправление состояло в том, чтобы создать простое приложение на 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. Я обработал несколько тысяч изображений и не нашел неправильной идентификации.

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

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);
}
1
По вопросам рекламы [email protected]