Как извлечь данные клиентов из их образа KTP?

Что такое KYC?

Вы когда-нибудь регистрировались в приложении, и вас просят загрузить изображение удостоверения личности (например, KTP) для обновления вашей учетной записи? Такая процедура обычно называется KYC (Знай своего клиента). Это процесс проверки личности клиентов. Это необходимо для обеспечения надежности нашей клиентской базы и уменьшения количества случаев мошенничества с использованием личных данных.

В Bukalapak KYC выполняется, позволяя пользователям загружать свое изображение KTP и фотографию селфи с их удостоверением личности. Пользователь проверяется путем проверки идентификационных данных внутри KTP и сравнения изображения KTP на фотографии селфи.

Автоматическая проверка KYC

Проблема в процессе проверки KYC состоит в том, чтобы убедиться, что данные, введенные пользователями, верны. Таким образом, нам нужно «прочитать» данные в изображении KTP и сравнить KTP с фотографией селфи. Обычный способ сделать это - заставить агентов CS вручную проверять изображения. К сожалению, это может потребовать много времени и ресурсов. Таким образом, нам необходимо автоматизировать этот процесс. Обратите внимание, что в этой статье рассматривается только автоматизация извлечения данных из образа KTP.

На самом деле, есть некоторые третьи стороны, которые предоставляют услугу по автоматическому извлечению данных из изображений KTP и их проверке, однако это может взимать с нас высокую плату. Таким образом, мы разработали сервис самостоятельно. Разработанный нами сервис принимает изображение KTP в качестве входных данных и возвращает пользовательские данные в KTP в качестве выходных данных (например, провинция, город, NIK, имя, место рождения и дата рождения, пол, семейное положение и т. Д.).

Архитектура этого сервиса следующая:

Шаг 1: OCR (оптическое распознавание символов)

Чтобы иметь возможность извлекать данные, мы должны читать тексты внутри изображения. Таким образом, нам понадобится OCR. Вместо того, чтобы создавать систему OCR с нуля, мы можем использовать существующую. Это обычная тема, и для OCR уже существует множество исследований и библиотек. В этом случае мы используем Google Cloud Vision (GCV).

Достаточно легко извлечь текст из изображения с помощью Vision API. Например, если у нас есть изображение «sample_ktp.png» и у нас уже есть ключ API «my_gcvision_api_key.json», мы можем просто запустить следующий скрипт Python:

from google.cloud import vision
from google.cloud.vision import types
from google.protobuf.json_format import MessageToDict
import sys
client = vision.ImageAnnotatorClient.from_service_account_file(
  “my_gcvision_api_key.json”)
text_response = client.text_detection(image=image)
text_response = MessageToDict(text_response)

После этого процесса мы получим данные о фрагментах слова внутри изображения и их координаты. Итак, для каждого слова есть «описание» и четыре пары x и y. Для упрощения обработки мы преобразуем данные в метку (x1, y1) в (x4, y4) как четыре координаты, w (ширина) и h (высота). Результат примера можно увидеть на следующем изображении:

Шаг 2: Распознавание сущности

Из предыдущего шага мы получаем информацию только о существующих словах и их положениях. Однако мы не знаем, какой из них представляет НИК, имя, пол и т. Д.
Таким образом, следующий процесс - выяснить эти сущности. Для этого есть несколько подходов. Раньше я использовал сопоставление с образцом на основе регулярных выражений, но результат был не очень хорош. Итак, я использую метод поиска позиции поля сущности, а затем нахожу соответствующее значение.

Например, мы хотим найти имя. Во-первых, нам нужно найти слово «нама». Мы можем напрямую отфильтровать ls_word, где label = ‘nama’. Однако иногда мы обнаруживаем опечатку в результате распознавания текста, например «Нама» становится «нма». Чтобы справиться с этим, я использую расстояние Левенштейна и нахожу слово с наименьшим расстоянием редактирования до искомого слова. Сценарий выглядит следующим образом.

field_keywords = ‘nama’
ls_dist = [levenshtein(field_keywords, word[‘label’].lower()) for word in ls_word]
index = np.argmin(ls_dist)
ls_word[index]

Теперь мы знаем местонахождение слова «нама». Следующая задача - выяснить его значение, которое в основном стоит справа от слова «нама». Мы можем просто просмотреть слова со схожей позицией y. Однако это будет проблематично, если изображение будет наклонено. Пример можно увидеть на следующем изображении. Мы уже нашли позицию слова «нама». Если проследить горизонтальную линию вправо (красную), то вместо названия мы получим НИК. Лучше всего следовать направлению текста на основе его градиента.

Вот код для этого:

import math
def calDeg(x1,y1,x2,y2):
  myradians = math.atan2(y1-y2, x1-x2)
  mydegrees = math.degrees(myradians)
  mydegrees = mydegrees if mydegrees >= 0 else 360+mydegrees
  return mydegrees
x,y = ls_word[index][‘x1’], ls_word[index][‘y1’]
w = ls_word[index][‘w’]
degree = calDeg(ls_word[index][‘x1’],ls_word[index][‘y1’],ls_word[index][‘x2’],ls_word[index][‘y2’])
ls_y = np.asarray([np.abs(y-word[‘y1’]) < 300 for word in ls_word])
value_words = [ww for ww, val in zip(ls_word,ls_y) if (val and np.abs(calDeg(x,y,ww[‘x1’],ww[‘y1’])-degree)< 3)]
value_words = [val for val in value_words if len(val[‘label’].replace(‘ ‘,’’).replace(‘:’,’’))>0]
field_value = “”
for val in value_words:
field_value = field_value + ‘ ‘+ str(val[‘label’])
field_value = field_value.lstrip()

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

Код Python в Github

Полный базовый сценарий этого инструмента извлечения KTP доступен в следующем репозитории на github: http://github.com/bukalapak/KTPextractor. Это один из проектов с открытым исходным кодом, которые у нас есть в Букалапаке. Вы также можете внести свой вклад и помочь нам улучшить эту услугу.

Оценка

Используя эту услугу, проверка KYC может быть выполнена быстро (в 50 раз быстрее! Мы можем обработать до 50 000 KYC за один день, а не только 1.000 в день при ручной проверке). Мы также можем напрямую обнаруживать проблемные изображения KYC (например, изображение не KTP, изображение размытое / нечитаемое, данные в KTP неполные и т. Д.). Согласно нашей внутренней оценке, среди успешных KYC сервису удалось успешно обнаружить 85% данных. Таким образом, этот сервис довольно эффективен, чтобы заменить людей, проверяющих процесс KYC :)