如何从 ORB 算法计算百分比分数?

use*_*r93 5 python opencv image-processing computer-vision orb

我正在使用 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"
Run Code Online (Sandbox Code Playgroud)

我确实在 Stack Overflow 上找到了一个解决方案,可以使用Matlabsift算法执行此操作,但是是否有任何外部库可以轻松地与 Python 一起使用以通过 OpenCV 执行此操作?

bfr*_*ris 5

我不认为关键点匹配适合百分比分数,无论您使用 ORB 还是 SIFT。

我认为OP指的是这篇文章,它确实给出了如何得出每场比赛得分的提示。分数是匹配对中每个项目的距离的平方,即

m.distance**2 + n.distance**2
Run Code Online (Sandbox Code Playgroud)

其中mn来自 OP 发布的代码。然而,这个分数与百分比没有任何相似之处。我不确定你能找到一个。OP 代码中的幻数 0.75 在某些地方被称为 Lowe 比率,该比率最初由 Lowe 在[DG Lowe, “Distinctive Image Features from Scale-Invariant Keypoints”, Intl Journal of Computer Vision 60(2), 91-110,2004]。它与任何品质因数一样好,但需要根据关键点检测算法(例如 ORB、SIFT 等)进行调整。为了确定是否找到了良好的匹配,通常会调整 Lowe 比率,然后计算良好匹配的数量。单应性教程(适用于 OpenCV 2.4 或3.4.1)就是一个很好的例子

我使用的是 OpenCV 3.4,ORB 确实返回值,只是没有 SIFT 那么多。使用教程图像“box.png”和“box_in_scene.png”,我得到 79 个与 SIFT 的“良好”匹配和 7(!)与 ORB 的“良好”匹配。

然而,如果我将 ORB 的幻数从 0.75 提高到 0.89,我会得到 79 个“好”匹配。

使用 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()
Run Code Online (Sandbox Code Playgroud)

使用这些图像作为输入:

在此输入图像描述 在此输入图像描述

我得到这些结果: 在此输入图像描述 在此输入图像描述

然而,值得注意的是,ORB 提供了更多 Bastoncini 盒子之外的虚假比赛。