如何从ORB算法计算%得分?

问题描述 投票:3回答:2

我正在使用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做到这一点?

python opencv image-processing computer-vision orb
2个回答
2
投票

无论您使用的是ORB还是SIFT,我都认为关键点匹配不会影响百分比。

我认为OP指的是this post,它提供了如何得出每场比赛得分的提示。得分是匹配对中每个项目的距离的平方,即

m.distance**2 + n.distance**2

其中m和n来自OP发布的代码。然而,这个分数与百分比没有相似之处。而且我不确定你会找到一个。 OP代码中0.75的神奇数字在某些地方被称为Lowe比率,这是Lowe in [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“box.png”和“box_in_scene.png”,我与SIFT获得79个“好”匹配,与ORB匹配7个(!)“好”匹配。

但是,如果我将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()

使用这些图像进行输入:

enter image description here enter image description here

我得到了这些结果:enter image description here enter image description here

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


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,如果没有足够的描述符,一些图片将是“吸引者”。

© www.soinside.com 2019 - 2024. All rights reserved.