我正在使用OpenCV 2.4.9的ORB算法和Python来比较图像。 ORB算法不会将相似性分数作为百分比返回。有没有办法做到这一点?
使用ORB比较图像的代码如下
img1 = cv2.imread("img11.jpg",0)
img2 = cv2.imread("img2.jpg",0)
# Initiate ORB detector
orb = cv2.ORB()
# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)
# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING)
matches = bf.knnMatch(des1, trainDescriptors = des2, k = 2)
good = []
for m,n in matches:
if m.distance < 0.75*n.distance:
good.append([m])
if len(good) > 20:
print "similar image"
我确实在Stack Overflow上找到了一个使用 Matlab 为 sift 算法执行此操作的解决方案,但是有没有外部库可以很容易地与Python一起使用那与OpenCV?
答案 0 :(得分:2)
我不认为关键点匹配会使百分比得分,无论您使用的是ORB还是SIFT。
我认为OP指的是this post,它确实提供了如何获得每场比赛得分的提示。得分是匹配对中每个项目距离的平方,即
m.distance**2 + n.distance**2
其中 m 和 n 来自OP发布的代码。然而,这个分数与百分比没有相似之处。而且我不确定你是否会找到一个。 OP代码中0.75的幻数在某些地方被称为Lowe比率,这是Lowe在 [D G Lowe, "Distinctive Image Features from Scale-Invariant Keypoints", Intl Journal of Computer Vision 60(2), 91-110, 2004]中首次提出的。它与任何优点一样好,但需要根据关键点检测算法(例如ORB,SIFT等)进行调整。要确定您是否找到了一个好的匹配,调整Lowe比率然后计算好匹配的数量是很常见的。 Homography教程(适用于OpenCV 2.4或3.4.1)就是这个
的一个很好的例子我使用OpenCV 3.4和ORB确实返回值,而不是像SIFT那样多。使用tutorial images&#34; box.png&#34;和&#34; box_in_scene.png&#34;,我得到79&#34;好&#34;匹配SIFT和7(!)&#34;好&#34;与ORB匹配。
然而,如果我将ORB的幻数0.75提高到0.89,我得到79&#34;好&#34;匹配。
使用Python 3.4.4和OpenCV 3.4的完整代码。对于OpenCV 2.4.9,语法和操作应该非常相似:
# This time, we will use BFMatcher.knnMatch() to get k best matches.
# In this example, we will take k=2 so that we can apply ratio test
# explained by D.Lowe in his paper.
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img1 = cv.imread('box.png',0) # queryImage
img2 = cv.imread('box_in_scene.png',0) # trainImage
method = 'ORB' # 'SIFT'
lowe_ratio = 0.89
if method == 'ORB':
finder = cv.ORB_create()
elif method == 'SIFT':
finder = cv.xfeatures2d.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = finder.detectAndCompute(img1,None)
kp2, des2 = finder.detectAndCompute(img2,None)
# BFMatcher with default params
bf = cv.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)
# Apply ratio test
good = []
for m,n in matches:
if m.distance < lowe_ratio*n.distance:
good.append([m])
msg1 = 'using %s with lowe_ratio %.2f' % (method, lowe_ratio)
msg2 = 'there are %d good matches' % (len(good))
img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,good, None, flags=2)
font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(img3,msg1,(10, 250), font, 0.5,(255,255,255),1,cv.LINE_AA)
cv.putText(img3,msg2,(10, 270), font, 0.5,(255,255,255),1,cv.LINE_AA)
fname = 'output_%s_%.2f.png' % (method, magic_number)
cv.imwrite(fname, img3)
plt.imshow(img3),plt.show()
使用这些图像进行输入:
然而,值得注意的是,ORB提供了更多的Bastoncini盒子之外的虚假比赛。
答案 1 :(得分:0)
一个答案虽然可能不是最好的答案,但可能是:
(...)
matches = bf.knnMatch(des1,des2, k=2)
# Apply ratio test
good = []
for m,n in matches:
if m.distance < lowe_ratio*n.distance:
good.append([m])
dist = 1 - len(good) / (max(len(pic1.description), len(pic2.description)))
然后您将获得%值,这对图片排名比较好。如果将 max 更改为 min ,则某些图片如果没有足够的描述符,将成为“吸引者”。