Пакетная программа 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
Ответы
Ответ 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
Надеюсь, это поможет кому-то.