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

Пакетная программа OCR для PDF файлов

Это было задано раньше, но я действительно не знаю, помогают ли ответы. Вот моя проблема: у меня есть куча (10 000 или около того) pdf файлов. Некоторые из них были текстовыми файлами, которые были сохранены с использованием функции печати Adobe (так что их текст прекрасен, и я не хочу рисковать их привинчиванием). И некоторые были отсканированными изображениями (поэтому у них нет текста, и мне придется согласиться на OCR). Файлы находятся в одном каталоге, и я не могу сказать, что именно. В конечном итоге я хочу превратить их в .txt файлы, а затем выполнить строчную обработку. Поэтому я хочу, чтобы было максимально точное распознавание текста.

Кажется, люди рекомендовали:

  • adobe pdf (у меня нет лицензионной копии этого так... плюс, если ABBYY finereader или что-то лучше, зачем платить за него, если я его не буду использовать)
  • ocropus (я не могу понять, как использовать эту вещь),
  • Tesseract (кажется, что в 1995 году это было здорово, но я не уверен, есть ли что-то более точное, плюс он не делает PDF файлы изначально, и мне нужно преобразовать в TIFF, что вызывает проблему, поскольку я У меня есть лицензионная копия acrobat, поэтому я не знаю, как бы конвертировать 10 000 файлов в tiff. Кроме того, я не хочу, чтобы 10 000 30 страниц документов превращались в 30 000 индивидуальных изображений TIFF.)
  • wowocr
  • pdftextstream (с 2009 года)
  • ABBYY FineReader (по-видимому, его "$$$", но я потрачу 600 долларов, чтобы сделать это, если эта вещь значительно лучше, то есть имеет более точный ocr).

Также я программирую n00b, поэтому, если вам понадобится неделя, чтобы научиться делать что-то, я бы предпочел заплатить $$$. спасибо для ввода/опыта.

Кстати, я запускаю Linux Mint 11 64 бит и/или Windows 7 64 бит.

Вот другие темы:

Пакетное OCRing PDF файлы, которые еще не были OCR'd

OCR с открытым исходным кодом

Подход к извлечению PDF-текста с использованием OCR

https://superuser.com/info/107678/batch-ocr-for-many-pdf-files-not-already-ocred

4b9b3361

Ответ 1

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

"У меня нет лицензионной копии acrobat, поэтому я не знаю, как конвертировать 10 000 файлов в tiff".

Вы можете конвертировать PDF файлы в TIFF с помощью Free (как в свободном доступе) и бесплатно (как в пиве) Ghostscript. Ваш выбор, если вы хотите сделать это в Linux Mint или в Windows 7. Командная строка для Linux:

gs \
 -o input.tif \
 -sDEVICE=tiffg4 \
  input.pdf

"Я не хочу, чтобы 10000 документов на 30 страниц превратились в 30 000 индивидуальных изображений tiff"

У вас могут быть "многостраничные" TIFF. Выше команда создает такие TIFF вкуса G4 (факс tiff). Если вам даже нужны одностраничные TIFF, вы можете изменить команду:

gs \
 -o input_page_%03d.tif \
 -sDEVICE=tiffg4 \
  input.pdf

Часть имени файла %03d автоматически преобразуется в последовательность 001, 002, 003 и т.д.

Предостережения:

  • Разрешение по умолчанию для устройства вывода tiffg4 равно 204x196 dpi. Вы, вероятно, хотите получить лучшее значение. Чтобы получить 720 dpi, вы должны добавить -r720x720 в командную строку.
  • Кроме того, если ваша установка Ghostscript использует букву как размер носителя по умолчанию, вы можете ее изменить. Вы можете использовать -gXxY для установки widспасибоheight в точках устройства. Таким образом, чтобы получить размеры страницы формата A4 A4 в ландшафте, вы можете добавить параметр -g8420x5950.

Таким образом, полная команда, которая управляет этими двумя параметрами, для вывода 720 dpi на A4 в портретной ориентации, будет читать:

gs \
 -o input.tif \
 -sDEVICE=tiffg4 \
 -r720x720 \
 -g5950x8420 \
  input.pdf

Ответ 2

Полагаю, что я попытаюсь внести свой вклад, отвечая на мой собственный вопрос (написали хороший код для себя и не могли сделать это без помощи этого совета). Если вы кота pdf файлы в unix (ну, osx для меня), то файлы pdf, у которых есть текст, будут иметь в них слово "Font" (как строка, но смешанное с другим текстом) b/c, что файл сообщает Adobe о том, какие шрифты должны отображаться.

Команда cat в bash, похоже, имеет тот же результат, что и чтение файла в двоичном режиме в python (используя режим "rb" при открытии файла вместо "w" или "r" или "a" ). Поэтому я предполагаю, что все файлы PDF, содержащие текст, имеют слово "Font" в двоичном выходе и что никакие файлы только для изображений никогда не будут. Если это всегда верно, то этот код будет составлять список всех файлов PDF в одной директории с текстом и отдельным списком тех, которые имеют только изображения. Он сохраняет каждый список в отдельный .txt файл, затем вы можете использовать команду в bash для перемещения файлов PDF в соответствующую папку.

После того, как вы разместите их в своих собственных папках, вы можете запустить пакетное решение ocr только в pdf файлах в папке images_only. Я еще не получил этого еще (очевидно).

    import os, re

    #path is the directory with the files, other 2 are the names of the files you will store your lists in

    path = 'C:/folder_with_pdfs'
    files_with_text = open('files_with_text.txt', 'a')
    image_only_files = open('image_only_files.txt', 'a')


    #have os make a list of all files in that dir for a loop
    filelist = os.listdir(path)

    #compile regular expression that matches "Font"
    mysearch = re.compile(r'.*Font.*', re.DOTALL)

    #loop over all files in the directory, open them in binary ('rb'), search that binary for "Font"
    #if they have "Font" they have text, if not they don't
    #(pdf does something to understand the Font type and uses this word every time the pdf contains text)
    for pdf in filelist:
        openable_file = os.path.join(path, pdf)
        cat_file = open(openable_file, 'rb')
        usable_cat_file = cat_file.read()
        #print usable_cat_file
        if mysearch.match(usable_cat_file):
            files_with_text.write(pdf + '\n')
        else:
            image_only_files.write(pdf + '\n')

Чтобы переместить файлы, я ввел эту команду в оболочку bash:

cat files_with_text.txt | while read i; do mv $i Volumes/hard_drive_name/new_destination_directory_name; done 

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

Ответ 3

Это интересная проблема. Если вы готовы работать в Windows в .NET, вы можете сделать это с помощью dotImage (отказ от ответственности, я работаю в Atalasoft и написал большую часть OCR код двигателя). Позвольте разбить проблему на куски - сначала выполняется итерация по всем вашим файлам PDF:

string[] candidatePDFs = Directory.GetFiles(sourceDirectory, "*.pdf");
PdfDecoder decoder = new PdfDecoder();

foreach (string path in candidatePDFs) {
    using (FileStream stm = new FileStream(path, FileMode.Open)) {
        if (decoder.IsValidFormat(stm)) {
            ProcessPdf(path, stm);
        }
    }
}

Получает список всех файлов, которые заканчиваются на .pdf, и если файл является допустимым pdf, вызывает процедуру для его обработки:

public void ProcessPdf(string path, Stream stm)
{
    using (Document doc = new Document(stm)) {
        int i=0;
        foreach (Page p in doc.Pages) {
            if (p.SingleImageOnly) {
                ProcessWithOcr(path, stm, i);
            }
            else {
                ProcessWithTextExtract(path, stm, i);
            }
            i++;
        }
    }
}

Это открывает файл как объект Document и спрашивает, есть ли на каждой странице только изображение. Если это будет OCR-страница, иначе она будет извлекать текст:

public void ProcessWithOcr(string path, Stream pdfStm, int page)
{
    using (Stream textStream = GetTextStream(path, page)) {
        PdfDecoder decoder = new PdfDecoder();
        using (AtalaImage image = decoder.Read(pdfStm, page)) {
            ImageCollection coll = new ImageCollection();
            coll.Add(image);
            ImageCollectionImageSource source = new ImageCollectionImageSource(coll);
            OcrEngine engine = GetOcrEngine();
            engine.Initialize();
            engine.Translate(source, "text/plain", textStream);
            engine.Shutdown();
        }
    }
}

что это делает, растеризует страницу PDF в изображение и помещает ее в форму, приемлемую для engine.Translate. Это не обязательно нужно делать так: можно получить объект OcrPage от движка от AtalaImage, вызвав Recognize, но тогда клиентский код будет перебирать структуру и выписывать текст.

Вы заметите, что я ушел из GetOcrEngine() - мы делаем доступными 4 механизма OCR для использования клиентами: Tesseract, GlyphReader, RecoStar и Iris. Вы бы выбрали тот, который лучше всего подходит для ваших нужд.

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

public void ProcessWithTextExtract(string path, Stream pdfStream, int page)
{
    using (Stream textStream = GetTextStream(path, page)) {
        StreamWriter writer = new StreamWriter(textStream);
        using (PdfTextDocument doc = new PdfTextDocument(pdfStream)) {
            PdfTextPage page = doc.GetPage(i);
            writer.Write(page.GetText(0, page.CharCount));
        }
    }
}

Это извлекает текст с данной страницы и записывает ее в выходной поток.

Наконец, вам понадобится GetTextStream():

public Stream GetTextStream(string sourcePath, int pageNo)
{
    string dir = Path.GetDirectoryName(sourcePath);
    string fname = Path.GetFileNameWithoutExtension(sourcePath);
    string finalPath = Path.Combine(dir, String.Format("{0}p{1}.txt", fname, pageNo));
    return new FileStream(finalPath, FileMode.Create);
}

Будет ли это 100% -ным решением? Нет. Конечно нет. Вы могли бы представить страницы PDF, содержащие одно изображение с обводкой коробки вокруг него - это явно провалило бы проверку только изображения, но не возвратило бы полезный текст. Вероятно, лучший подход состоит в том, чтобы просто использовать извлеченный текст, и если это ничего не возвращает, попробуйте механизм OCR. Переход от одного подхода к другому - это вопрос написания другого предиката.

Ответ 4

Самый простой подход - использовать один инструмент, такой как ABBYY FineReader, Omnipage и т.д. для обработки изображений в одной партии без необходимости сортировать их в сканированных и не отсканированных изображениях. Я считаю, что FineReader конвертирует PDF в изображения, прежде чем выполнять OCR.

Использование механизма OCR даст вам такие функции, как автоматическая коррекция, обнаружение ориентации страницы, порог изображения, despeckling и т.д. Это функции, которые вам придется покупать для библиотеки изображений и программировать самостоятельно, и может оказаться трудно найти оптимальный набор параметров для ваших 10 000 PDF файлов.

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

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

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

Ответ 5

Я написал небольшую обертку для движка Abbyy OCR4LINUX CLI (IMHO, это не так дорого) и Tesseract 3.

Обертка может пакетно конвертировать файлы вроде:
$ pmocr.sh --batch --target=pdf --skip-txt-pdf /some/directory

script использует pdffonts, чтобы определить, был ли файл PDF уже OCRed, чтобы пропустить их. Кроме того, script может работать как системный сервис для мониторинга каталога и запуска действия OCR, как только файл входит в каталог.

Script можно найти здесь:
https://github.com/deajan/pmOCR

Надеюсь, это поможет кому-то.