Привет,

Прошу прощения, что давно не писал - исправляюсь.

Возможно вам доводилось сталкиваться с задачей, когда надо распознать в удобочитаемый (или редактируемый) вид сканированные или отфотографированные изображения каких-нибудь текстов. Например, редкие учебные пособия, переснятые в перерыве или, например, куча сканированной рабочей документации. Основная проблема в такой ситуации состоит в том, что FineReader, являющийся, на мой взгляд, лидером в точности распознавания, не имеет встроенных средств для пакетной обработки. Существует корпоративная версия, но она, по сути, решает несколько другие задачи: работа по расписанию и т.п. В общем, не совсем то, что нужно. Теоретически, существует Abbyy Recognition Server - но он стоит совсем других денег и лицензируется на объем обрабатываемых документов (либо абсолютное значение, либо помесячный лимит), что не вполне подходит под мои требования =)

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

После дискуссии на форуме Abbyy, обнаружил скрипт автоматизации FineReader 8 средствами абсолютно бесплатного средства автоматизации действий с интерфейсом AutoIT. Выяснилось, что с девятым FR скрипт работает не совсем корректно, посему пришлось дорабатывать напильником.

Результат тестировался в русских версиях Vista HB и Windows XP Prof, и, в общем, работает =) В скрипте есть ряд задержек, выявленных эмпирическим путем. Допускаю, что серией экспериментов эти задержки можно сократить.

Как пользоваться скриптом?

  1. Скачайте и установите AutoIT.
  2. Установите ABBYY FineReader.
  3. Установите в системе английскую раскладку клавиатуры умолчанию
  4. Запустите FR и его переключите его интерфейс на английский язык
  5. Откройте и распознайте в ручном режиме любые (желательно небольшие) файлы изображений из папки, предварительно установив необходимые опции распознавания (это нужно для сохранения настроек FR, эти же настройки будут применяться ко всем автоматически распознаваемым файлам)
  6. После сохранения распознанного вручную файла, FR нужно закрыть; в диалоговом окне сохранения файла нужно выключить галочку “Открыть сохраненный файл в родном приложении”, иначе открытые файлы очень быстро съедят память
  7. При поврежденном файле изображения скрипт приостанавливает выполнение и ждет нажатия кнопки, после чего выполнение продолжается.
  8. При необходимости изменить в коде скрипта константы $FR_dir, $drive и $START_dir
  9. Чтобы построить список папок, выполните небольшой батничек, приведенный под катом, результат его работы положите в папку $START_dir. Обратите внимание, что пустые папки тоже попадают в список, поэтому их надо вычистить вручную.

Известные слабые места скрипта:

  1. Для каждой итерации FR запускается заново
  2. Существуют случайные баги в работе скрипт - подозреваю, это связано с AutoIT, но у меня скрипт стабильно работает при выключенном explorer.exe, отключенном антивирусе, остановленных некритичных службах XP и остановленном антивирусе - чтобы минимизировать возможность воздействия на работу скрипта
  3. Задержка в 15 секунд после сохранения файла - чудовищно велика при большом количестве папок; уменьшение ее, однако, влечет увеличение сбоев в работе скрипта

Вот так - сыро, местами глючно, но чертовски дешево (100 € за FineReader Prof).
Под катом - код для AutoIT и bat-файл для сбора дерева папок. Удачного распознавания! Спасибо Alexrey (ник U235 на форумах ABBYY) за скрипты для FR8.


list_folders.bat:

  1. chcp 1251
  2. dir /ad /b /on /s > list_folder.txt

automate.au3:

  1. Const $drive = "c:"Const $START_Dir = $drive&"\recognize\"$firsttime = 1;   00      Create logfile
  2.  
  3. $log = FileOpen($START_Dir&"log.txt", 2)
  4.  
  5. If $log = -1 Then
  6.  
  7. MsgBox(0, "Error", "Unable to open file.")
  8.  
  9.  
  10.  
  11. ;       01      Open Finereader
  12.  
  13. Const $FR_dir = "C:\Program Files\ABBYY FineReader 9.0\"
  14.  
  15. FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&"      "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"Set FR9 dir to C:\Program Files\ABBYY FineReader 9.0\"&@CRLF)
  16.  
  17. AutoItSetOption ( "WinTitleMatchMode" , 2 )
  18.  
  19. FileWriteLine($log, @MDAY&"/"&@MON&"/"&@YEAR&"      "&@HOUR&":"&@MIN&":"&@SEC&" >>> "&"Set WinTitleMatchMode to non-strict"&@CRLF)
  20.  
  21. ;       02      Open Folders list
  22.  
  23. $folder_list = FileOpen($START_Dir&"list_folder.txt", 0)
  24.  
  25. If $folder_list = -1 Then
  26.  
  27. MsgBox(0, "Error", "Unable to open list file.")
  28.  
  29.  
  30.  
  31. ;       04      Working loop
  32.  
  33. While 1;$firsttime<3
  34.  
  35. SendKeepActive("ABBYY")
  36.  
  37. $folder = FileReadLine($folder_list)
  38.  
  39. $t_fname = StringReplace($folder,"\","-")
  40.  
  41. $fname = StringReplace($t_fname,$drive,$firsttime&amp;"")
  42.  
  43. If @error = -1 Then ExitLoop
  44.  
  45. If StringLen($folder) < 1 Then ExitLoop
  46.  
  47. Run($FR_dir&amp;"FineReader.exe")
  48.  
  49. FileWriteLine($log, @MDAY&amp;"/"&amp;@MON&amp;"/"&amp;@YEAR&amp;"      "&amp;@HOUR&amp;":"&amp;@MIN&amp;":"&amp;@SEC&amp;" >>> "&amp;"FR9 - Start"&amp;@CRLF)
  50.  
  51. FileWriteLine($log, @MDAY&amp;"/"&amp;@MON&amp;"/"&amp;@YEAR&amp;"      "&amp;@HOUR&amp;":"&amp;@MIN&amp;":"&amp;@SEC&amp;" >>> "&amp;"Got directory: "&amp;$folder&amp;@CRLF)
  52.  
  53. WinWaitActive("ABBYY")
  54.  
  55. FileWriteLine($log, @MDAY&amp;"/"&amp;@MON&amp;"/"&amp;@YEAR&amp;"      "&amp;@HOUR&amp;":"&amp;@MIN&amp;":"&amp;@SEC&amp;" >>> "&amp;"Got active FR9"&amp;@CRLF)
  56.  
  57. SendKeepActive("ABBYY")
  58.  
  59. Send("^o")
  60.  
  61.  
  62. ControlSetText ( "Open", "", "Edit1", $folder); открытие папки
  63.  
  64. Sleep(3000)
  65.  
  66. FileWriteLine($log, @MDAY&amp;"/"&amp;@MON&amp;"/"&amp;@YEAR&amp;"      "&amp;@HOUR&amp;":"&amp;@MIN&amp;":"&amp;@SEC&amp;" >>> "&amp;"Set folder to "&amp;$folder&amp;@CRLF)
  67.  
  68. ControlClick ( "Open", "", "Button3" )
  69.  
  70. ;MsgBox(0,"Folder",$folder)
  71.  
  72. FileWriteLine($log, @MDAY&amp;"/"&amp;@MON&amp;"/"&amp;@YEAR&amp;"      "&amp;@HOUR&amp;":"&amp;@MIN&amp;":"&amp;@SEC&amp;" >>> "&amp;"ControlClick button3"&amp;@CRLF)
  73.  
  74. Sleep(1000);
  75.  
  76. If ControlListView  ( "Open", "", "SysListView321", "GetItemCount" ) = 0 Then
  77.  
  78. Send("{ESC}")
  79.  
  80.  
  81.  
  82. ControlListView  ( "Open", "", "SysListView321", "SelectAll" );
  83.  
  84. FileWriteLine($log, @MDAY&amp;"/"&amp;@MON&amp;"/"&amp;@YEAR&amp;"      "&amp;@HOUR&amp;":"&amp;@MIN&amp;":"&amp;@SEC&amp;" >>> "&amp;"Select all files"&amp;@CRLF)
  85.  
  86. ;WinActivate("Open")
  87.  
  88. Sleep(500)
  89.  
  90. Send("{ENTER}")
  91.  
  92. FileWriteLine($log, @MDAY&amp;"/"&amp;@MON&amp;"/"&amp;@YEAR&amp;"      "&amp;@HOUR&amp;":"&amp;@MIN&amp;":"&amp;@SEC&amp;" >>> "&amp;"Enter to select"&amp;@CRLF)
  93.  
  94. Sleep(1000)
  95.  
  96. WinWait("Adding","Completed")
  97.  
  98. FileWriteLine($log, @MDAY&amp;"/"&amp;@MON&amp;"/"&amp;@YEAR&amp;"      "&amp;@HOUR&amp;":"&amp;@MIN&amp;":"&amp;@SEC&amp;" >>> "&amp;"All pages ready"&amp;@CRLF)
  99.  
  100. WinActivate("Adding","Completed")
  101.  
  102. Send("{ENTER}")
  103.  
  104. FileWriteLine($log, @MDAY&amp;"/"&amp;@MON&amp;"/"&amp;@YEAR&amp;"      "&amp;@HOUR&amp;":"&amp;@MIN&amp;":"&amp;@SEC&amp;" >>> "&amp;"Ready to save…"&amp;@CRLF)
  105.  
  106. WinActivate("ABBYY")
  107.  
  108. Send("^s")
  109.  
  110. WinWait("Save")
  111.  
  112. Sleep(500);
  113.  
  114. ControlSetText ( "Save", "", "Edit1", $folder&amp;"\"&amp;$fname );
  115.  
  116. Sleep(1000)
  117.  
  118. ControlClick ( "Save", "", "Button2" )
  119.  
  120. ;Send("{ENTER}")
  121.  
  122. Sleep(1000);
  123.  
  124. WinWaitClose("Saving")
  125.  
  126. FileWriteLine($log, @MDAY&amp;"/"&amp;@MON&amp;"/"&amp;@YEAR&amp;"      "&amp;@HOUR&amp;":"&amp;@MIN&amp;":"&amp;@SEC&amp;" >>> "&amp;"Saved to "&amp;$folder&amp;"\"&amp;$fname&amp;@CRLF)
  127.  
  128. sleep(15000)
  129.  
  130. WinActivate("ABBYY")
  131.  
  132. sleep(1000)
  133.  
  134. Send("!f")
  135.  
  136. Send("c")   ;Закрываем пакет
  137.  
  138. WinWait("ABBYY","Do you want to save")
  139.  
  140. Sleep(1000);
  141.  
  142. ControlClick ( "ABBYY","Do", "Button2" )
  143.  
  144. Sleep(1000);
  145.  
  146. Send("!f")
  147.  
  148. Send("x")
  149.  
  150. $firsttime=$firsttime+1
  151.  
  152.  
  153. FileWriteLine($log, @MDAY&amp;"/"&amp;@MON&amp;"/"&amp;@YEAR&amp;"      "&amp;@HOUR&amp;":"&amp;@MIN&amp;":"&amp;@SEC&amp;" >>> "&amp;"Total of "&amp;$firsttime&amp;"processed"&amp;@CRLF)
[Slashdot] [Digg] [News2] Бобрдобр [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]