Сравнение подписей с использованием Opencv - PullRequest
0 голосов
/ 26 мая 2020

Я хотел сравнить сходство между двумя подписями.

Python version : 3.7.7
OpenCv version : 4.2.0

Вот что я сделал до сих пор:

from cv2 import *
import numpy as np


#uploading images
template = cv2.imread("C://Users//subhr//Ams_1.jpg")
original = cv2.imread("C://Users//subhr//Ams_2.jpg")

#resizing images
template = cv2.resize(template,(528,152))
cv2.imshow("template image", template)
cv2.waitKey(0)
cv2.destroyAllWindows()
template.shape #row.columns
original = cv2.resize(original,(528,152))
cv2.imshow("original image", original)
cv2.waitKey(0)
cv2.destroyAllWindows()

#ORB Detector
orb = cv2.ORB_create()

original = cv2.Canny(original, 50, 200)
template = cv2.Canny(template, 50, 200)

# key points and descriptor calculation
kp1, desc_1 = orb.detectAndCompute(template, None)
kp2, desc_2 = orb.detectAndCompute(original, None)

#creating matches
matcher = cv2.DescriptorMatcher_create(cv2.DescriptorMatcher_BRUTEFORCE_HAMMING)
matches_1 = matcher.knnMatch(desc_1, desc_2, 2)
len(matches_1)

result = cv2.drawMatchesKnn(original, kp1 , template, kp2, matches_1, None)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

#distance similarity
good_points = []
for m,n in matches_1:
    if m.distance < 0.8* n.distance:
        good_points.append(m)
len(good_points)

result = cv2.drawMatches(original, kp1 , template, kp2, good_points, None)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

print(len(kp1))
print(len(kp2))

#calculating ratio
print("How good is the match : ",len(kp1)/len(good_points))

На этом этапе я пробовал orb и akaze, я хотел использовать SIFT, но он недоступен. Я пробовал Opencv версии 3.4 , но безуспешно.

Есть ли лучший способ сравнить сходства в сигнатурах и стандартизировать весь процесс?

ссылка для изображений: https://ibb.co/yhvTrng, https://ibb.co/xfBzCgW

Спасибо.

1 Ответ

1 голос
/ 26 мая 2020

Вы не привели ни одного примера изображений, но даже в этом случае я не уверен, что использование таких точек функций, как orb или Kaze / Akaze, было бы хорошей идеей. Те более или менее все еще обнаруживают угловые точки, когда сравнение сигнатур с некоторой степенью точности, похоже, требует гораздо больше знаний (кривизна и т. Д. c). Это похоже на то, что простая сверточная сеть будет хороша. Я думаю, что вы можете использовать, например, такую ​​архитектуру:

signature --> Convnet --> head-1 --> signature embedding  ------>---
                      |                                             |---> (Hinge) loss
                      |                                             |
                       --> head-2 --> signtature embedding ---->----

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

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

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

Низкоуровневые функции, которые вы извлекаете (не извлекайте ORB, он разработан, чтобы быть быстрым, а не точным, придерживайтесь KAZE или AKAZE, если можете) захватывать локальную информацию, но для распознавания подписей важно то, как они пространственно распределены (распределение должно быть примерно одинаковым в аналогичных подписях). Это может быть решено одним или обоими этими вещами: 1) Измените способ оценки сходства, чтобы включить пространственное распределение вместо того, чтобы просто полагаться на количество общих точек характеристик 2) Разработайте вручную дополнительный элемент высокого уровня, который фиксирует глобальные аспекты подписей (это может быть простое соотношение высоты / ширины или более сложное с учетом кривизны и т. д. c).

...