Дипломная (вкр): Оптическое распознавание символов

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Рис. 25 Области интереса

.        Группировка областей по линиям, сортировка по площадям, высотам и расстояниям между областями

.        Разделение областей в поля

Рис. 26 Необходимые поля

2.5.2 Алгоритм локальной адаптивной бинаризации

1.      Пороги для поверхности изображения вычисляются, во время скольжения прямоугольного окна(каждый пиксель бинаризуется основываясь на информации о своих соседях).

.        Порог «T» в центральном пикселе окна вычисляется по формуле:

T = m - kα(m - M), α = 1 - , R = max(s),

где «m» - минимальное значение интенсивности пикселя изображения в «оттенках серого» в окне, «k» - константа, установленная равной 0.2, «M» - минимальное значение интенсивности пикселя во всем изображении в «оттенках серого», «S» - стандартное отклонение, «R» - максимальное из стандартных отклонений по всем окрестностям.

3.      Затем изображение сравнивается с пороговой поверхностью и все пиксели с интенсивностью большей пороговой, делаются белыми(255), а все интенсивности меньшие пороговой делаются черными(0)

.        Для данного алгоритма единственный входной параметр - размер окна.

Входной параметр - размер окна:

1.      Экспериментально было установлено, что лучшие результаты распознавания достигаются с размером окна равным половине высоты текста.

.        Таким образом, алгоритм способен обрабатывать образцы с различным размером текста

.        Но требуется система оценивающая высоту текста

2.5.3 Оценка высоты текста

1.      Для каждой ячейки на изображении в «оттенках серого» вычисляются интенсивности. Это позволяет получить массив дисперсий, у которых длина равна высоте изображения.

.        Области дисперсии, у которых расхождение больше порога «Tv» - рассматриваются как текст.(«Tv» - среднее значение всего набора дисперсии)

.        Медианная ширина зон текста большая «Tv» - высота текста.

2.5.4 Удаление линий (через анализ области вокруг текста)

Шаги алгоритма:

1.      Локализация связанных областей текста в бинаризованном изображении.

.        Обнаружение линий на изображении без текста.

. Удаление линий из оригинального изображения.

Связанные области текста:

1.      Высота текста нам известна(h)

.        Бинаризованное изображение расширяется с помощью следующего ядра:


3.      Изображение обрабатывается нормализованным hxh ядром:


4.      Результирующая обработка ограничена порогом в 0.25

.        Полученные блобы (Blob - регион цифрового изображения, обладающий постоянными свойствами) вероятнее всего были получены из текста, т.о связанные регионы теста найдены.


Обнаружение линий

1.      Удаление всех зон текста (все, что находится внутри связанных регионов)

.        Применяем трансформацию Хафа чтобы найти горизонтальные линии (Линии в большинстве случаев «сломаны» и обладают не одинаковой толщиной, поэтому трансформация Хафа применяется с порогом равным половине высоты, и максимальном расстоянию между линиями равному половине ширины)

.        Предыдущий шаг найдет список позиций горизонтальных линий

Удаление линий

1.      Используем позиции горизонтальных линий и извлекаем пиксели из оригинального изображения, которые принадлежат линиям, но не к текстовым символам.

.        Предполагаем, что толщина линий не постоянна, но не больше чем h/10.

.        Для каждой возможной толщины, и каждой координаты на линии, накладываем на оригинальное изображение маску и отмечаем все пиксели ,которые совпадают с маской.

.        Создаем отклонение, двигая маску вверх-вниз со стартовой позиции. Данное перемещение не должно быть больше толщины линии.

Используемая маска:

,

где «d» - это толщина линии.

.        Нули добавлены, чтобы убедиться, что маска не накладывается на текст.

.        Если при наложении маски, найдены пиксели подходящие ей, то он маркируются для удаления.




Входное изображение должно содержать текст, с окружающей его зоной, достаточно большой, чтобы иметь фоновые линии после того, как текстовые зоны будут удалены. Линии могут быть под углом, пока возможно их обнаружение по кусочкам. При обработке, текст не будет потерян. Иногда небольшие участки текста остаются, но они могут быть удалены в последующих шагах обработки.

2.6 Обученные данные

Обучающая выборка состоит из стандартного пакета русского языка для tesseract. Результаты обработки с ее помощью были не идеальны, поэтому были улучшены путем внесения изменений в файлы обучающей выборки.

2.7 Результат работы программы



Рис. 27 Результат работы программы


На данный момент, система демонстрирует 94-95% точность распознавания.

2.8 Описание графического интерфейса пользователя


Разработанное приложение обладает простым интуитивно понятным интерфейсом. При запуске приложения пользователь видит основное окно (рис. 28)

Рис. 28 Стартовый экран приложения

Для того, чтобы система начала свою работу необходимо нажать кнопку «Open» и выбрать изображение паспорта, затем нажатием кнопки «Recognize» запускается процесс распознавания данных с изображения паспорта. Результат работы программы будет выведен в соответствующие графы под изображением (Рис. 29.)

Рис. 29 Результат работы программы

2.9 Тестирование функции распознавания паспортных данных


Исходными данными для тестирования являются сканированные изображения паспортов и файлы с проверочными данными для каждого изображения в определенном формате. На данный момент корректные данные заносятся в проверочные файлы вручную, в дальнейшем планируется разработать GUI для удобного редактирования данных.

Рис. 30. Проверочные данные для тестирования

2.9.1 Процесс тестирования

В процессе работы утилиты для каждого изображения формируется файл с распознанными данными в том же формате, что и проверочный файл. Далее проводится сравнение полученных и корректных данных используя Расстояние Левенштейна.

2.9.2 Результат тестирования

Результатом тестирования являются сгенерированные статистические файлы для каждого изображения, и сводный файл в формате html для визуализации результатов.

Рис. 31 Результат тестирования.

В целом проводилось тестирование на 50 различных паспортах, ошибка составила 5%. Данный процент ошибки - в основном результат применения различных шрифтов в разных регионах нашей страны, и не идеальность алгоритма удаления фона.

Заключение

распознавание символ документ оптический

В настоящие время качественные системы распознавания текста достаточно дороги, поэтому недостаточно широко распространены. Например, FineReader 12 показывает лучший результат. Он великолепно распознает как сканированные, так и сфотографированные изображения. Однако, минимальная его стоимость составляет 80€ за лицензию на 10000 распознаваний в год. Данная же система не имеет таких ограничений и может быть установлена, например, в бухгалтерии или отделе кадров любой компании, для автоматизации сбора и обновления данных. Наше OCR приложение на базе Tesseract позволяет с достаточно высокой степенью точности распознавать символы, при наличии различных шумов и помех, благодаря разработанному алгоритму предварительной обработки изображений и системой постобработки текста, основанной на словарном контроле результатов. Несомненным преимуществом нашей системы является возможность быстрой доработки под иной формат документов и интуитивно понятный интерфейс пользователя. Кроме того, разработанное решение было успешно внедрено в Территориальный фонд Обязательного медицинского страхования Нижегородской области, следовательно, имеет практическую значимость.

На данный момент у данного модуля существует один значительный недостаток касательно поддержки русского языка: данные недостаточно обучены, что не дает такого же высокоточного результата, как с международными языками, но со временем этот недостаток нивелируется.

В дальнейшем планируется разработка web-based прототипа приложения, расширение возможностей по распознаванию данных: поддержка других видов документов, борьба с шумами, более качественные метод удаления фона, видоизменение стандартного алгоритма определения базовой линии (используя openCV).

Список литературы


1.      Богданов В., Ахметов К. Системы распознавания текстов в офисе. // Компьютер-пресс - 1999 №3, с.40-42.

.        Павлидис Т. Алгоритмы машинной графики и обработки изображений. М:, Радиоисвязь, 1986

.        Shani U. Filling Regions in Binary Raster Images - a Graph-theoretic Approach. // SIGGRAPH'80, pp 321-327.

.        Merrill R.D. Representation of Contours and Regions for Efficient Computer Search. // CACM, 16 (1973), pp. 69-82.

.        Pavlidis T. Filling Algorithms for Raster Graphics. // CGIP, 10 (1979), pp. 126141.

6.      <https://habrahabr.ru/post/112442/>

7.      Lieberman H. How to Color in a Coloring Book. // SIGGRAPH'78, Atlanta, Georgia, (August, 1978), pp. 111-116. PublishedbyACM.

8.      Fuller, R. (2004). Fuzzy logic and neural nets in intelligent systems. In C. Carlsson (Ed.)Information Systems Day, pp. 74-94. Turku: Abo Academi University Press.

.        Melin P., Urias J., Solano D., Soto M., Lopez M., Castillo O., Voice Recognition with Neural Networks, Type-2 Fuzzy Logic and Genetic Algorithms. Engineering Letters, 13:2, 2006.

10.    R.W. Smith, The Extraction and Recognition of Text from Multimedia Document Images, PhD Thesis, University of Bristol, November 1987.

.        R.W.Smith, “A Simple and Efficient Skew Detection Algorithm via Text Row Accumulation”, Proc. of the 3rd Int. Conf. on Document Analysis and Recognition (Vol. 2), IEEE 1995, pp. 1145-1148.

.        R.W. Smith, An Overview of the Tesseract OCR Engine, IEEE 2007 pp. 629 - 633

.        http://yann.lecun.com/exdb/mnist/

14.    International Journal of Computer Vision 57(2), 137-154, 2004

15.    Canny Edge Detection Tutorial by Bill Green, 2002.

.        Shapiro, L. G. & Stockman, G. C: "Computer Vision", page 137, 150. PrenticeHall, 2001

17.    OpenCV Python tutorials(<http://opencv-python-tutroals.readthedocs.org/>)

18.    Багрова И. А., Грицай А. А., Сорокин С. В., Пономарев С. А., Сытник Д. А. Выбор признаков для распознавания печатных кириллических символов // Вестник Тверского Государственного Университета 2010 г., 28, стр. 59-73

19.    Journal of Signal and Information Processing, 2013, 4, 173-175

20.    <https://ru.wikipedia.org/wiki/Tesseract>

21.    <https://en.wikipedia.org/wiki/Comparison_of_optical_character_recognition_software>

22.    Квасников В.П., Дзюбаненко А.В. Улучшение визуального качества цифрового изображения путем поэлементного преобразования // Авиационно-космическая техника и технология 2009 г., 8, стр. 200-204

.        <https://habrahabr.ru/company/abbyy/blog/225215/>

24.    Mark S. Nixon and Alberto S. Aguado. Feature Extraction and Image Processing. - Academic Press, 2008. - С. 88.

25.    Hsueh, M. (2011). Interactive text recognition and translation on a mobile device. Electrical Engineering and Computer Sciences, 57, 47-60.

.        Gllavata, G. & Ewerth, R. (2003). A robust algorithm for text detection in images. New York: Halstead Press.

.        Bieniecki, W. & Grabowski, S. (2007). Image preprocessing for improving OCR accuracy. Columbia: Columbia University Press.

Приложение

.        Prototype.py:ImageImportError:PIL import Imagesafepytesseractcv2multiprocessing import Poolautorotatecleanbgpostactionsfindboxesdo_recognize(img, dbg=''):

""" save image and process with tesseract """dbg != '':= dbg + '_tmp.png'.imwrite(filename, img)= Image.fromarray(img, 'RGB')= safepytesseract.image_to_string(img, lang='rus')resultrecognize(img, rot, (l1, t1, r1, b1), coeff, post=None, dbg='', shrinkboxfactor=0):

""" prepares picture for recognition, passes picturetesseract and does post actions:- image to process

(l, t, r, b) - box to look into- rotation flag for the box above

(l1, t1, r1, b1) - box to ignore within (l, t, r, b)- debug flag- array of post actions- by how much factor of height will the box be shrinked from each side (left and right) aftercleaning and before it is passed to OCR. Must be >=0

"""

# do rotation if neededrot:= cv2.transpose(img)= cv2.flip(img, 0)= cleanbg.clean_bg((img, coeff, True))shrinkboxfactor < 0:ValueError("shrinkbox must be >=0")= int(img.shape[0] * shrinkboxfactor)shrinkpixels > 0:= img[:, shrinkpixels:-shrinkpixels, :]

# wash the box which is to be ignoredl1 != 0 or t1 != 0 or r1 != 0 or b1 != 0:rr in range(t1, b1):pp in range(l1, r1):[rr][pp] = [255, 255, 255]= do_recognize(img, dbg + str(coeff) if dbg != '' else '')= postactions.do_post_actions(result, post)dbg != '':resultresult

# noinspection PyArgumentListrecognize_wrapper(args):

""" wrapper function to be passedthe process pool """recognize(*args)do_box(img, (l, t, r, b), rot, (l1, t1, r1, b1), post=None, agressive=0, dbg='', expandboxfactor=0):

""" Does recognition for image within given box """dbg != '':'_do_box (l:%u t:%u r:%u b:%u rot:%u)' % (l, t, r, b, rot)rot != 0: # don't expand rotated images= 0expandboxfactor != 0:-= int(expandboxfactor * (b-t))+= int(expandboxfactor * (b-t))

# crop the box= img[t:b, l:r]agressive:frange(x, y, jump):x < y:x+= jump= frange(0.0, 2.0, (2.0 - 0.0) / agressive)= Pool(4)= pool.map(recognize_wrapper,

[(img.copy(), rot, (l1, t1, r1, b1),, post, dbg, expandboxfactor) for coeff in coeffs])= postactions.do_sift(attempts, dbg):= 1.0= recognize(img, rot, (l1, t1, r1, b1), coeff, post, dbg, expandboxfactor)result

# noinspection PyArgumentListdo_box_wrapper(args):

""" wrapper function to be passedthe process pool """do_box(*args)= (('surname', (0.44, 0.85, 0.54, 0.62), 0, (0, 0, 0, 0), [postactions.post_remove_newlines,.post_remove_spaces]),

('name', (0.51, 0.80, 0.62, 0.67), 0, (0, 0, 0, 0), [postactions.post_remove_newlines,.post_remove_spaces]),

('patronymic', (0.51, 0.80, 0.67, 0.71), 0, (0, 0, 0, 0), [postactions.post_remove_newlines,.post_remove_spaces]),

('series', (0.92, 0.98, 0.05, 0.25), 90, (0, 0, 0, 0), [postactions.post_remove_newlines,.post_remove_spaces]),

('number', (0.92, 0.98, 0.25, 0.48), 90, (0, 0, 0, 0), [postactions.post_remove_newlines,.post_remove_spaces]),

('whom', (0.10, 0.92, 0.09, 0.20), 0, (0.00, 0.16, 0.00, 0.22), [postactions.newlines_to_spaces,.post_remove_spaces_before_dots,.smart_replacement]),

('when', (0.18, 0.399, 0.20, 0.25), 0, (0, 0, 0, 0), [postactions.post_remove_newlines,.post_remove_spaces]),

('birthdate', (0.57, 0.90, 0.71, 0.75), 0, (0, 0, 0, 0), [postactions.post_remove_newlines,.post_remove_spaces,.commas_to_dots]),

('birthplace', (0.36, 0.90, 0.75, 0.86), 0, (0.00, 0.06, 0.00, 0.10), [postactions.newlines_to_spaces,._remove_spaces_before_dots]),

('gender', (0.38, 0.49, 0.71, 0.75), 0, (0, 0, 0, 0), [postactions.post_remove_newlines,.post_remove_spaces,.remove_dots_and_commas]))process_image(filename, dbg=0, agressive=0, rotate=1, adaptive_bboxes=False, expandboxfactor=0):

""" innter1 function """dbg:filename'agressive = ', agressive

# read and rotate the picture= cv2.imread(filename)rotate:= autorotate.auto_rotate((img, filename if dbg != 0 else '')), cols, _ = img.shaperows == 0 or cols == 0:''

# print findboxes.get_boxes(img, dbg)

# print findboxes.get_boxes()adaptive_bboxes:= findboxes.get_boxes(img, dbg)= ''name, rects, rot, ignore, post in bboxes:

# print rects= name + ': 'r in rects:= do_box(img, r, rot, ignore, post, expandboxfactor=expandboxfactor)name == 'series':= out[:4]name == 'number':= out[-6:]+= out+= ' '+= fieldres + '\n'result:= findboxes.get_boxes()agressive:

# for agressive recognition process boxes one by one;

# do_box() starts its own process for every coeff;

# python doesn't allow to start child processes from childs= []name, (l, r, t, b), rot, (l1, r1, t1, b1), post in bboxes:.append(do_box(img,

(int(l1 * r * cols), int(t1 * b * rows), int(r1 * r * cols), int(b1 * b * rows)),=post,=agressive,=filename + "_" + name if dbg != 0 else ''))out # [(result,weights),...]:

# for fast recognition start pool of workers and

# and recognize each box in its separate process

'''

# uncomment this and comment the code below for serial processing= ''name, (l, r, t, b), rot, (l1, r1, t1, b1), post in boxes:+= name + ': ' + do_box(img.copy(),

(int(l * cols), int(t * rows), int(r * cols), int(b * rows)),,

(int(l1 * r * cols), int(t1 * b * rows), int(r1 * r * cols),(b1 * b * rows)),,

,+ "_" + name if dbg != 0 else '') + '\n'out

'''= Pool(4)= pool.map(do_box_wrapper, [(img.copy(),

(int(l * cols), int(t * rows), int(r * cols), int(b * rows)),,

(int(l1 * r * cols), int(t1 * b * rows), int(r1 * r * cols),(b1 * b * rows)),,

,+ "_" + name if dbg != 0 else '')name, (l, r, t, b), rot, (l1, r1, t1, b1), post in bboxes])= [name for name, _, _, _, _ in boxes]= [name + ": " + out[names.index(name)] for name in names]reduce(lambda aa, bb: aa + '\n' + bb, result)

Источник: https://www.bibliofond.ru/detail.aspx?id=896877