你可能想要了解一下特征匹配。其思想是在两幅图像中找到特征并进行匹配。这种方法通常用于在另一幅图像中找到模板(例如标志)。特征本质上可以被描述为人类在图像中发现的有趣的事物,例如拐角或开放空间。虽然有许多类型的特征检测技术,但我的建议是使用尺度不变特征变换(SIFT)作为特征检测算法。SIFT对图像平移、缩放、旋转具有不变性,对光照变化部分具有不变性,并且对局部几何失真具有鲁棒性。这似乎符合您的规格,因为图像可以具有稍微不同的比例。
给定你提供的两张图片,我们使用
FLANN特征匹配器来尝试匹配特征点。为了确定这两张图片是否相同,我们可以通过预设阈值来跟踪通过
David G. Lowe描述的比率测试的匹配数量。简单地说,比率测试检查匹配是否模糊,并应该被移除,可以将其视为异常值去除技术。我们可以计算通过此测试的匹配数以确定这两张图片是否相同。以下是特征匹配结果:
![](https://istack.dev59.com/R9ngs.webp)
![](https://istack.dev59.com/vIPko.webp)
Matches: 42
这些点代表所有检测到的匹配项,而绿色线条表示通过比率测试的“好匹配项”。如果不使用比率测试,则会绘制所有点。通过这种方式,您可以将此过滤器用作阈值,仅保留最佳匹配特征。
我用Python实现了它,对Rails不是很熟悉。希望这有所帮助,祝好运!
代码
import numpy as np
import cv2
image1 = cv2.imread('1.jpg', 0)
image2 = cv2.imread('2.jpg', 0)
sift = cv2.xfeatures2d.SIFT_create(700)
kp1, des1 = sift.detectAndCompute(image2, None)
kp2, des2 = sift.detectAndCompute(image1, None)
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1,des2,k=2)
matchesMask = [[0,0] for i in range(len(matches))]
count = 0
for i,(m,n) in enumerate(matches):
if m.distance < 0.15*n.distance:
count += 1
matchesMask[i]=[1,0]
draw_params = dict(matchColor = (0,255,0),
matchesMask = matchesMask,
flags = 0)
result = cv2.drawMatchesKnn(image2,kp1,image1,kp2,matches,None,**draw_params)
print('Matches:', count)
cv2.imshow('result', result)
cv2.waitKey()
compare
命令行工具有一个-subimage-search
开关。 - Stefan