Пакетное распознавание документов при помощи FineReader и AutoIT
Привет,
Прошу прощения, что давно не писал – исправляюсь.
Возможно вам доводилось сталкиваться с задачей, когда надо распознать в удобочитаемый (или редактируемый) вид сканированные или отфотографированные изображения каких-нибудь текстов. Например, редкие учебные пособия, переснятые в перерыве или, например, куча сканированной рабочей документации. Основная проблема в такой ситуации состоит в том, что FineReader, являющийся, на мой взгляд, лидером в точности распознавания, не имеет встроенных средств для пакетной обработки. Существует корпоративная версия, но она, по сути, решает несколько другие задачи: работа по расписанию и т.п. В общем, не совсем то, что нужно. Теоретически, существует Abbyy Recognition Server – но он стоит совсем других денег и лицензируется на объем обрабатываемых документов (либо абсолютное значение, либо помесячный лимит), что не вполне подходит под мои требования =)
Посему, было решено обходиться малыми средствами, а сэкономленное пустить на компьютер, который будет заниматься распознаванием.
После дискуссии на форуме Abbyy, обнаружил скрипт автоматизации FineReader 8 средствами абсолютно бесплатного средства автоматизации действий с интерфейсом AutoIT. Выяснилось, что с девятым FR скрипт работает не совсем корректно, посему пришлось дорабатывать напильником.
Результат тестировался в русских версиях Vista HB и Windows XP Prof, и, в общем, работает =) В скрипте есть ряд задержек, выявленных эмпирическим путем. Допускаю, что серией экспериментов эти задержки можно сократить.
Как пользоваться скриптом?
- Скачайте и установите AutoIT.
- Установите ABBYY FineReader.
- Установите в системе английскую раскладку клавиатуры умолчанию
- Запустите FR и его переключите его интерфейс на английский язык
- Откройте и распознайте в ручном режиме любые (желательно небольшие) файлы изображений из папки, предварительно установив необходимые опции распознавания (это нужно для сохранения настроек FR, эти же настройки будут применяться ко всем автоматически распознаваемым файлам)
- После сохранения распознанного вручную файла, FR нужно закрыть; в диалоговом окне сохранения файла нужно выключить галочку “Открыть сохраненный файл в родном приложении”, иначе открытые файлы очень быстро съедят память
- При поврежденном файле изображения скрипт приостанавливает выполнение и ждет нажатия кнопки, после чего выполнение продолжается.
- При необходимости изменить в коде скрипта константы $FR_dir, $drive и $START_dir
- Чтобы построить список папок, выполните небольшой батничек, приведенный под катом, результат его работы положите в папку $START_dir. Обратите внимание, что пустые папки тоже попадают в список, поэтому их надо вычистить вручную.
Известные слабые места скрипта:
- Для каждой итерации FR запускается заново
- Существуют случайные баги в работе скрипт – подозреваю, это связано с AutoIT, но у меня скрипт стабильно работает при выключенном explorer.exe, отключенном антивирусе, остановленных некритичных службах XP и остановленном антивирусе – чтобы минимизировать возможность воздействия на работу скрипта
- Задержка в 15 секунд после сохранения файла – чудовищно велика при большом количестве папок; уменьшение ее, однако, влечет увеличение сбоев в работе скрипта
Вот так – сыро, местами глючно, но чертовски дешево (100 € за FineReader Prof).
Под катом – код для AutoIT и bat-файл для сбора дерева папок. Удачного распознавания! Спасибо Alexrey (ник U235 на форумах ABBYY) за скрипты для FR8.
list_folders.bat:
chcp 1251 dir /ad /b /on /s > list_folder.txt
automate.au3:
Const $drive = "c:"Const $START_Dir = $drive&"\recognize\"$firsttime = 1; 00 Create logfile $log = FileOpen($START_Dir&"log.txt", 2) If $log = -1 Then MsgBox(0, "Error", "Unable to open file.") Exit EndIf ; 01 Open Finereader Const $FR_dir = "C:\Program Files\ABBYY FineReader 9.0\" FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"Set FR9 dir to C:\Program Files\ABBYY FineReader 9.0\"&@CRLF) AutoItSetOption ( "WinTitleMatchMode" , 2 ) FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"Set WinTitleMatchMode to non-strict"&@CRLF) ; 02 Open Folders list $folder_list = FileOpen($START_Dir&"list_folder.txt", 0) If $folder_list = -1 Then MsgBox(0, "Error", "Unable to open list file.") Exit EndIf ; 04 Working loop While 1;$firsttime<3 SendKeepActive("ABBYY") $folder = FileReadLine($folder_list) $t_fname = StringReplace($folder,"\","-") $fname = StringReplace($t_fname,$drive,$firsttime&"") If @error = -1 Then ExitLoop If StringLen($folder) < 1 Then ExitLoop Run($FR_dir&"FineReader.exe") FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"FR9 - Start"&@CRLF) FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"Got directory: "&$folder&@CRLF) WinWaitActive("ABBYY") FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"Got active FR9"&@CRLF) SendKeepActive("ABBYY") Send("^o") WinWaitActive("Open") ControlSetText ( "Open", "", "Edit1", $folder); открытие папки Sleep(3000) FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"Set folder to "&$folder&@CRLF) ControlClick ( "Open", "", "Button3" ) ;MsgBox(0,"Folder",$folder) FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"ControlClick button3"&@CRLF) Sleep(1000); If ControlListView ( "Open", "", "SysListView321", "GetItemCount" ) = 0 Then Send("{ESC}") ContinueLoop EndIf ControlListView ( "Open", "", "SysListView321", "SelectAll" ); FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"Select all files"&@CRLF) ;WinActivate("Open") Sleep(500) Send("{ENTER}") FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"Enter to select"&@CRLF) Sleep(1000) WinWait("Adding","Completed") FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"All pages ready"&@CRLF) WinActivate("Adding","Completed") Send("{ENTER}") FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"Ready to save..."&@CRLF) WinActivate("ABBYY") Send("^s") WinWait("Save") Sleep(500); ControlSetText ( "Save", "", "Edit1", $folder&"\"&$fname ); Sleep(1000) ControlClick ( "Save", "", "Button2" ) ;Send("{ENTER}") Sleep(1000); WinWaitClose("Saving") FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"Saved to "&$folder&"\"&$fname&@CRLF) sleep(15000) WinActivate("ABBYY") sleep(1000) Send("!f") Send("c") ;Закрываем пакет WinWait("ABBYY","Do you want to save") Sleep(1000); ControlClick ( "ABBYY","Do", "Button2" ) Sleep(1000); Send("!f") Send("x") $firsttime=$firsttime+1 WEnd FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&" "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"Total of "&$firsttime&"processed"&@CRLF)
Похожих записей нет.
3 Комментариев
March 29th, 2008
Привет!
В бат-файле первая строчка уползла во вторую
March 30th, 2008
Сергей, привет. Исправил) Вообще, AutoIT оказался крайне нестабильной штукой, увы. Сейчас работает питоний скрипт, из следующей записи – там все намного лучше.
August 28th, 2008
Спасибо. Действительно все конкретно и очень практично. Будем применять.
Добавить комментарий