По роду службы, каждый месяц, у меня образовывается некоторое количество сканов документов, с которыми нужно произвести определенные действия и переместиь в архив. Перед этим всем, файлам нужно дать осмысленные имена. Так как файлов больше, чем порог терпения, я озадачился автоматическим переименованием сканов документов.
Для выполнения задачи необходима программа для оптического распознавания символов (OCR). Выбор пал на свободно распространяемый и, что не мало важно, работающий оффлайн Tesseract от Google.
В Arch Linux ставится так:
pacman -S tesseract tesseract-data-eng tesseract-data-rus
Как выяснилось, МФУ жмёт TIFF в формат, который Tesseract не воспринимает. Из за чего потребуется библиотека для работы с TIFF-изображениями:
pacman -S libtiff
Сначала работаем из консоли, чтобы получить proof of concept:
Преобразуем входной файл в надлежащий формат:
tiffcp -c lzw -i Keyocera-6525_20180507160147107474.tif,0 /tmp/scan.tif 2> /dev/null
Выполняем распознавание символов с выводом на стандартный вывод:
tesseract /tmp/scan.tif stdout -l rus
В результате, файл формата A4 с разрешением 600dpi в градациях серого, распознался за 7 секунд с качеством распознавания, позволяющим осуществить поиск ключевых слов для выполнения каталогизации.
Теперь, когда мы убедились, что это возможно, пишем скрипт для автоматического выполнения всех действий.
Писать будем на Python, так что ставим модуль pytesseract:
pip install pytesseract
Сам скрипт конвертирует файлы в текущей директории в удобноваримый для Tesseract вид, делает распознавание, ищет на странице номер договора и делает переименование в соответствии с правилами.
#!/bin/env python
# -*- coding: utf-8 -*-.
import os
from PIL import Image
import pytesseract
import re
import sys
import tempfile
if len(sys.argv) < 2:
print('USAGE:')
print('\t' + sys.argv[0] + ' file_prefix\n')
exit()
else:
pref = sys.argv[1]
rules = {
'договор1': 'контрагент1 услуга1',
'договор2': 'контрагент2 услуга1',
'договор3': 'контрагент1 услуга2',
}
tmpfile = tempfile.mktemp(dir='/tmp')
names = {}
for f in os.listdir():
ret = os.system('tiffcp -c lzw ' + f + ',0 ' + tmpfile + ' 2> /dev/null')
if ret!=0:
continue
image = Image.open(tmpfile)
text = pytesseract.image_to_string(image, lang="rus")
contract = text[re.search('№.*', text).start():].split()[1]
for i in rules.keys():
if contract.find(i)!=-1:
newname = pref + ' ' + rules[i]
if not names.get(rules[i]):
names[rules[i]] = 1
else:
names[rules[i]] += 1
newname += ' ' + str(names[rules[i]])
newname += '.tif'
os.rename(f, newname)
print(contract + '\t' + f + '\t->\t' + newname)
break
os.remove(tmpfile)