Пакетная программа OCR для PDF-файлов
Об этом уже спрашивали, но я не знаю, помогают ли мне ответы. Вот моя проблема: я получил кучу (около 10 000) PDF-файлов. Некоторые из них были текстовыми файлами, которые были сохранены с использованием функции печати Adobe (поэтому их текст идеален, и я не хочу рисковать их испортить). А некоторые были отсканированными изображениями (поэтому у них нет текста, и мне придется согласиться на распознавание текста). Файлы находятся в одном и том же каталоге, и я не могу сказать, который есть какой. В конечном итоге я хочу превратить их в файлы.txt и затем обработать их. Поэтому я хочу максимально точное распознавание текста.
Кажется, что люди рекомендовали:
- Adobe PDF (у меня нет лицензионной копии этого, так что... плюс, если ABBYY Finereader или что-то лучше, зачем платить, если я не буду его использовать)
- ocropus (я не могу понять, как использовать эту вещь),
- Тессеракт (кажется, что это было здорово в 1995 году, но я не уверен, что есть что-то более точное, плюс он не работает с pdfs изначально, и мне приходится конвертировать в TIFF. Это поднимает свою проблему, так как у меня нет лицензионная копия acrobat, поэтому я не знаю, как конвертировать 10 000 файлов в формат TIFF. Кроме того, я не хочу, чтобы 10 000 документов на 30 страницах превращались в 30 000 отдельных изображений TIFF).
- wowocr
- pdftextstream (это было с 2009 года)
- ABBYY FineReader (очевидно, это $$$, но я потрачу 600 долларов, чтобы сделать это, если эта вещь значительно лучше, то есть имеет более точный ocr).
Кроме того, я неравнодушен к программированию, поэтому, если на изучение того, как что-то сделать, уйдут недели, я бы скорее заплатил $$$. Спасибо за вклад / опыт.
Кстати, я использую Linux Mint 11 64 бит и / или Windows 7 64 бит.
Вот другие темы:
Пакетное распознавание PDF-файлов, которые еще не были OCR'd
Подход к извлечению текста в PDF с использованием OCR
https://superuser.com/questions/107678/batch-ocr-for-many-pdf-files-not-already-ocred
5 ответов
Просто, чтобы исправить некоторые из ваших заблуждений...
"У меня нет лицензионной копии acrobat, поэтому я не знаю, как конвертировать 10000 файлов в формат TIFF".
Вы можете конвертировать PDF-файлы в формат TIFF с помощью бесплатного (как в свободе) и бесплатного (как в пиве) Ghostscript. На ваш выбор, если вы хотите сделать это на Linux Mint или на Windows 7. Командная строка для Linux:
gs \
-o input.tif \
-sDEVICE=tiffg4 \
input.pdf
"Я не хочу, чтобы 10 000 документов на 30 страницах превратились в 30 000 отдельных изображений в формате TIFF"
Вы можете легко "многостраничные" TIFFs. Вышеприведенная команда создает такие TIFF-файлы типа G4 (Fax Tiff). Если вам даже нужны одностраничные TIFF, вы можете изменить команду:
gs \
-o input_page_%03d.tif \
-sDEVICE=tiffg4 \
input.pdf
%03d
часть выходного имени файла будет автоматически переведена в серию 001
, 002
, 003
и т.п.
Предостережения:
- Разрешение по умолчанию для
tiffg4
Выходное устройство составляет 204х196 точек на дюйм. Вы, вероятно, хотите лучшую ценность. Чтобы получить 720 точек на дюйм вы должны добавить-r720x720
в командной строке. - Кроме того, если ваша установка Ghostscript использует букву в качестве размера носителя по умолчанию, вы можете изменить его. Ты можешь использовать
-gXxY
установить widthxheight в точках устройства. Таким образом, чтобы получить размеры выходной страницы ISO A4 в альбомной ориентации, вы можете добавить-g8420x5950
параметр.
Таким образом, полная команда, которая управляет этими двумя параметрами, для вывода 720 точек на дюйм на A4 в портретной ориентации, будет выглядеть так:
gs \
-o input.tif \
-sDEVICE=tiffg4 \
-r720x720 \
-g5950x8420 \
input.pdf
Я подумал, что постараюсь внести свой вклад, ответив на мой собственный вопрос (я написал хороший код для себя и не смог бы сделать это без помощи этой доски). Если вы просматриваете pdf-файлы в unix (ну, для меня osx), то в pdf-файлах с текстом будет слово "Font" (как строка, но смешанная с другим текстом), так как Файл сообщает 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, я просто отредактировал его, так что он может быть глючным, Идк.
Это интересная проблема. Если вы готовы работать на 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 механизма распознавания для использования клиентом: 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. Переход от одного подхода к другому - это вопрос написания другого предиката.
Простейшим подходом было бы использование одного инструмента, такого как ABBYY FineReader, Omnipage и т. Д., Для обработки изображений в одном пакете без необходимости сортировки их в отсканированные и не отсканированные изображения. Я считаю, что FineReader в любом случае преобразует PDF-файлы в изображения перед выполнением распознавания текста.
Использование механизма оптического распознавания символов предоставит вам такие функции, как автоматическое выравнивание, определение ориентации страницы, определение порога изображения, удаление пятен и т. Д. Это те функции, для которых вам придется купить библиотеку обработки изображений и самостоятельно запрограммировать их, и может оказаться трудным найти оптимальный набор параметры для ваших 10000 PDF.
Использование автоматического подхода OCR будет иметь другие побочные эффекты в зависимости от входных изображений, и вы обнаружите, что получите лучшие результаты, если вы отсортируете изображения и установите оптимальные параметры для каждого типа изображений. Для точности было бы намного лучше использовать правильную процедуру извлечения текста в PDF, чтобы извлечь PDF-файлы с идеальным текстом.
В конце концов, все будет зависеть от времени и денег от качества результатов, которые вам нужны. В конце концов, коммерческая программа OCR станет самым быстрым и простым решением. Если у вас есть только текстовые документы, то подойдет как дешевая программа распознавания текста, так и дорогое решение. Чем сложнее ваши документы, тем больше денег вам придется потратить на их обработку.
Я попытался бы найти некоторые демонстрационные / пробные версии коммерческих механизмов распознавания и просто посмотреть, как они работают с вашими различными типами документов, прежде чем тратить слишком много времени и денег.
Я написал небольшую оболочку для движка Abbyy OCR4LINUX CLI (IMHO, не так уж и дорого) и Tesseract 3.
Оболочка может конвертировать файлы как:$ pmocr.sh --batch --target=pdf --skip-txt-pdf /some/directory
Скрипт использует pdffonts
чтобы определить, был ли уже распознан файл PDF, чтобы пропустить их. Кроме того, сценарий может работать как системная служба для мониторинга каталога и запуска действия OCR, как только файл входит в каталог.
Сценарий можно найти здесь:
https://github.com/deajan/pmOCR
Надеюсь, это кому-нибудь поможет.