• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Как стать рептилоидом и чипировать население: делаем онлайн-сервис с Computer Vision распознающий доки.

izobretatel

HDD-drive
Пользователь
Регистрация
21.06.2020
Сообщения
35
Реакции
17
Депозит
100
Дисклеймер:
Эта статья не про то как заработать быстро денег, про хитрую схему, написание стилера или новый метод обхода политик безопасности. Это немного о другом, не про схему, а про платформу. С примерами кода и в то же время, не оторвано от реальности и применимо на практике с пользой. Много второстепенного кода сознательно упущено, чтобы не отвлекать внимание от сути. Давай вместе поймем насколько это все может быть практично и какие возможности открывает?

Нынче модно стало контролировать население через биометрию. Загрузи паспорт, покажи лицо, сетчатка глаза, отпечаток, паспорт, мазок... Понятно, это для контроля и управления людьми государствами или корпорациями. И конечно - повышенная безопасность пользователей(какая забота)!

Что же делать, тут быть?

Создаем свой личный, маленький, теневой, электронный концлагер! Конечно же, с благими намерениями.

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

Python:
import pytesseract
from os import walk
from PIL import Image

Проходимся по папке с доками и загоняем каждый файл в tesseract:

Python:
lang = 'eng'
text += pytesseract.image_to_string(page, lang=lang) + "\n"

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

samples2/asdasdasfqfqweqwe.jpg
i VKPATHA @ UKRAINE W

Tun/ Type Koa nepxasu/ Country code Homep nacnoprta/ Passport N No. suas

nAcnoPpT P UKR FM522644
PASSPORT _ "Ipissuue/ Surname
KPVBOB'A3/KRYVOVIAZ

Im's/ Given Names

NABIO/PAVLO

Tpomagsucrso/ Nationality

YKPAIHA/UKRAINE

Ajata Hapogpxerus/ Date of birth 3anuc N2/ Record No,

29 [PY/DEC 82 19821229-05395

Crtatb/ Sex Micue HapomxeHis/ Place of birth

4/M KVIBCbKA OB/1./UKR
Jlata sugayi/ Date of issue Oprah, wo supas/ Authority
29BEP/MAR18 = ~—-3237

flava 3akin4eHHa cTpoky pii/ Date of expiry — Nignuc npeg’aBHuKa/ Holder's signature

a ., 29 BEP/MAR 28

P<UKRKRYVOVIAZ<<PAVLO<<<< <<< KKK KKK KKK KKK SKK
FM522644<2UKR8212292M28032941982122905395<02

i
samples2/asdasdasdqwfqwqweqwe.jpg
KARTU TANDA PENDUDUK

REPUBLIK INDONESIA
samples2/sadasdasdasdasdasd.jpg
\

Dre
te me) yp>>>>>>>>>>>> NTT AVZNW>> ZOTUVS
1 gp>a>>>>>>>> anol bZz0s2Wheyede ©
FT >>>v991z809701ageorze360VNN> ®

Я сохранил все данные в базу и теперь предстоить ее структурировать и написать шаблоны распознавания и тогда можно будет оценить общую эффективность. Вывожу все документы из базы с распознанным текстом в textarea под изображением:

doc_view.png



Теперь что? Давай соберем статистику, какие слова часто употребляются в полученном сыром тексте? Пока не будем склонять падежи и строить дерево графов, просто напишем ключевые слова и создатим текстовые шаблоны. Навскидку у меня получился вот такой шаблон по странам:

Python:
['indones', 'indonesia']
['peru', ]
['pakist', 'pakistan']
['turkey', 'turkiy']
['finland', ]
['india']
['kingdom', 'ireland', 'britain']
['deutsch', 'munchen']

А так же по типу документа:

Python:
['drive', 'driving']
['passport', 'pass']

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

Python:
for c in countries:
    for k in c:
        print('Looking for: ' + k)
        total = 0
        for cou in c[k]:
            regx = re.compile(".*"+cou+".*", re.IGNORECASE)
            result = collection.find({"images.doc_text": {"$regex":regx}})
            result_list = []
            for doc in result:
                result_list.append(doc)
            finds = len(result_list)
            total += finds
        print('Total: ' + str(total))

Из 2825 изображений различного качества, формата, повторов получилось распознать 523 страны и 359 документов:

Looking for: Germany
Total: 6
Looking for: GB
Total: 4
Looking for: Indonesia
Total: 42
Looking for: Indonesia
Total: 351
Looking for: Peru
Total: 11
Looking for: Pakistan
Total: 54
Looking for: Turkey
Total: 53
Looking for: Finland
Total: 2

Total countries: 523

Looking doc: Driving license
Total: 134
Looking doc: Passport
Total: 225

Total docs: 359

Что вполне себе неплохие результаты для беглого скриптинга. Но маловато...

Уже более наглядно и показательно. Давайте углубимся?! Подключаем компьютерное зрение.

Нет времени на теорию о RGB, пикселях и кодирования JPG, поэтому сразу перехожу к коду. Импортируем opencv2 и numpy

Python:
import cv2
import numpy as np

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

Находим примеры документов:

passports.jpg


И вырезаем отличительные признаки:

templates.jpg


Теперь давай вникнем в суть происходящего. Мы берем кусочек фото, накладываем и сверяем совпадение пикселей. Пока не берем никаких математических моделей, усреднений, медиан и пр. Но этот шаблон подойдет только к той фото, с которой он вырезан. Потому что размер, цвет и форма совершенно разные на каждом изображении каждого документа. Если прогнать шаблон по фоткам, то будет давать только одно совпадение. Как сделать шаблон более универсальным и подходящим для других изображений?

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

Python:
img_base = cv2.imread(img_base_path)
img_gray = cv2.cvtColor(img_base, cv2.COLOR_BGR2GRAY)

template = cv2.imread(img_template, 0)
template = cv2.Canny(template, 100, 350)

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

Python:
for scale in np.linspace(0.1, 1.0, 30)[::-1]:
    resized = imutils.resize(img_gray, width=int(img_gray.shape[1] * scale))
    r = img_gray.shape[1] / float(resized.shape[1])
    if resized.shape[0] < h or resized.shape[1] < w:
        break
    edged = cv2.Canny(resized, 20, 200)
    result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF)
    (_, max, _, maxL) = cv2.minmaxL(result)
    if True:
        clone = np.dstack([contrast, contrast, contrast])
        cv2.rectangle(clone, (maxL[0], maxL[1]), (maxL[0] + tW, maxL[1] + tH), (0, 0, 255), 2)
        cv2.imshow("Original", clone)
        cv2.imshow('Result', template)
        cv2.waitKey(0)

И вот пример результата:

result.png


Из ручной выборки в 20 документов, после долгой игры с cv2.Canny было распознано 12 штук, что является уже прекрасным результатом!

Второй проход по распознанию документов с помощью не самого сложного компьютерного зрения, уже может дать эффективность до 70%

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

Благодарю за внимание.

___

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

Кому принципиально важно наличие 1-click Run исходников в архиве - пришлю лично в ПМ, тем, кто проголосует за эту статью на конкурсе.

Все выигранные в конкурсе деньги благодаря вашим голосам за мои статьи - пойдут на создание одного из онлайн-сервисов для форума и форумчан. Предложения принимаются.
 
Последнее редактирование:
Как ты находишь mrz?
Через OCR либу, хоть pytesseract редко справляется с этой задачей, но можно натренить opencv, а потом докрутить еще чекер MRZ и получать очень наглядную статистику по документам:
  1. Тип дока
  2. Страна
  3. Имя, Фамилия
  4. Национальность
  5. Дата рождения
  6. Пол
  7. Expiry дата
 
Последнее редактирование:
не оторвано от реальности и применимо на практике с пользой
Оторвано и пока не применимо.
Ты скромно умолчал, как долго у тебя матчатся образцы через matchTemplate.
Нынче модно стало контролировать население через биометрию
При чем тут биометрия, если ты обрабатываешь только текст?

Как ты находишь mrz?
Никак не находит, он скармливает тессеракту всю картинку.

ТС, на каждом развороте паспорта есть лицо, в openCV есть встроенный детектор, если не два. Найдя лицо, можно определить ориентацию документа, можно прикинуть, где находятся области с текстом.

На многих документах есть МЧЗ, она относительно просто детектится, из ее данных гораздо проще получить страну и тип документа, например, чем используя твой подход. Потому что и шрифт и всю зону разрабатывали как раз для автоматического считывания.


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

Короче, ТС, все очень плохо.

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

ТС, на каждом развороте паспорта есть лицо, в openCV есть встроенный детектор, если не два. Найдя лицо, можно определить ориентацию документа, можно прикинуть, где находятся области с текстом.

На многих документах есть МЧЗ, она относительно просто детектится, из ее данных гораздо проще получить страну и тип документа, например, чем используя твой подход. Потому что и шрифт и всю зону разрабатывали как раз для автоматического считывания.
Да я вижу, OCR и mrz несовместимые понятия. Вместо OpenVC порекомендовал бы dlib.
 
Да я вижу, OCR и mrz несовместимые понятия. Вместо OpenVC порекомендовал бы dlib.

ТС, на каждом развороте паспорта есть лицо, в openCV есть встроенный детектор, если не два. Найдя лицо, можно определить ориентацию документа, можно прикинуть, где находятся области с текстом.

На многих документах есть МЧЗ, она относительно просто детектится, из ее данных гораздо проще получить страну и тип документа, например, чем используя твой подход. Потому что и шрифт и всю зону разрабатывали как раз для автоматического считывания.
Отлично, сенкс, в копилку возможных решений, работаем дальше?

Оторвано и пока не применимо.
Ты скромно умолчал, как долго у тебя матчатся образцы через matchTemplate.

Уже применяют пару чел, кто занимается разбором слитых баз картинок без сортировки.
Смотря какой сетап, на моем, без Сuda, на i7 ~2-3 секунды на изображение. Со скоростью человека.

При чем тут биометрия, если ты обрабатываешь только текст?

Пол, возвраст - это тоже биометрия. Добавить в dict шаблон и можно собрать. Статья для думающих.

Не надо на себя накидывать пуха и пихать без разбору умные слова, детали JPEG никакого отношения к задаче не имеют, ну или пруф.
Короче, ТС, все очень плохо.
Ты левой ногой набросал очень хреновый скрипт, умолчал о производительности, и почему-то считаешь, что это достойно участия в конкурсе. Я так не думаю, держу в курсе.
Пруф: векторизация при jpg и например массив пикселей png в pdf не распознаются одним и тем же cv2.TM_CCOEFF. Про пух учту в следующей статье.

Моя задача показать практическую концепцию, которую уже сейчас можно применять с пользой и привлечь интерес к дальнейшей разработке. Интересно, найдется ли отклик. Было бы тебя познавательно почитать, вижу в теме.
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх