Możesz rzucić okiem na dopasowanie funkcji. Chodzi o to, aby znaleźć funkcje na dwóch obrazach i dopasować je. Ta metoda jest powszechnie stosowana do znajdowania szablonu (powiedzmy logo) na innym obrazie. Cechę można w istocie opisać jako rzeczy, które ludzie mogą uznać za interesujące na obrazie, takie jak narożniki lub otwarte przestrzenie. Istnieje wiele rodzajów technik wykrywania cech, jednak moim zaleceniem jest użycie niezmiennej transformacji cech (SIFT) jako algorytmu wykrywania cech. SIFT jest niezmienny dla translacji obrazu, skalowania, obrotu, częściowo niezmienny dla zmian oświetlenia i odporny na lokalne zniekształcenie geometryczne. Wygląda na to, że pasuje do specyfikacji, w której obrazy mogą mieć nieco inne proporcje.
Biorąc pod uwagę dwa dostarczone obrazy, oto próba dopasowania funkcji za pomocą dopasowywania funkcji FLANN . Aby ustalić, czy dwa obrazy są takie same, możemy oprzeć je na pewnym z góry określonym progu, który śledzi liczbę dopasowań, które przejdą test współczynnika opisany w Wyróżniających cechach obrazu z Keypoints Scale-Invariant autorstwa Davida G. Lowe'a . Prostym wyjaśnieniem testu jest to, że test proporcji sprawdza, czy dopasowania są niejednoznaczne i powinny zostać usunięte, można to potraktować jako technikę usuwania wartości odstających. Możemy policzyć liczbę dopasowań, które przejdą ten test, aby ustalić, czy dwa obrazy są takie same. Oto wyniki dopasowania funkcji:
Matches: 42
Kropki oznaczają wszystkie wykryte dopasowania, podczas gdy zielone linie oznaczają „dobre dopasowania”, które pomyślnie przeszły test stosunku. Jeśli nie użyjesz testu proporcji, wszystkie punkty zostaną narysowane. W ten sposób możesz użyć tego filtra jako progu, aby zachować tylko najlepiej dopasowane funkcje.
Zaimplementowałem to w Pythonie, nie znam się zbyt dobrze na Railsach. Mam nadzięję, że to pomogło, powodzenia!
Kod
import numpy as np
import cv2
# Load images
image1 = cv2.imread('1.jpg', 0)
image2 = cv2.imread('2.jpg', 0)
# Create the sift object
sift = cv2.xfeatures2d.SIFT_create(700)
# Find keypoints and descriptors directly
kp1, des1 = sift.detectAndCompute(image2, None)
kp2, des2 = sift.detectAndCompute(image1, None)
# FLANN parameters
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50) # or pass empty dictionary
flann = cv2.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1,des2,k=2)
# Need to draw only good matches, so create a mask
matchesMask = [[0,0] for i in range(len(matches))]
count = 0
# Ratio test as per Lowe's paper (0.7)
# Modify to change threshold
for i,(m,n) in enumerate(matches):
if m.distance < 0.15*n.distance:
count += 1
matchesMask[i]=[1,0]
# Draw lines
draw_params = dict(matchColor = (0,255,0),
# singlePointColor = (255,0,0),
matchesMask = matchesMask,
flags = 0)
# Display the matches
result = cv2.drawMatchesKnn(image2,kp1,image1,kp2,matches,None,**draw_params)
print('Matches:', count)
cv2.imshow('result', result)
cv2.waitKey()
compare
narzędzie wiersza poleceń ImageMagick ma-subimage-search
przełącznik.