2017-12-07 1 views
0

Ich versuche SIFT für zwei Bilder zu verwenden und die Schlüsselpunkte mit BFMatcher in opencv übereinstimmen.OpenCV Länge der Übereinstimmungen in BFMatcher

Die Anzahl der Übereinstimmungen stimmt jedoch nicht mit der Anzahl der Abfragedeskriptoren überein. Kann jemand erklären, warum sie nicht gleich sind?

Nach docs match() - Funktion "Findet die beste Übereinstimmung für jeden Deskriptor aus einem Abfrage-Set."

import cv2 
import numpy as np 

im1 = cv2.imread("trex1.png", cv2.IMREAD_GRAYSCALE) 
im2 = cv2.imread("trex2.png", cv2.IMREAD_GRAYSCALE) 

sift = cv2.xfeatures2d.SIFT_create() 
kp1, des1 = sift.detectAndCompute(im1, None) 
kp2, des2 = sift.detectAndCompute(im2, None) 

im_kp1 = np.zeros(im1.shape, dtype=np.uint8) 
im_kp2 = np.zeros(im1.shape, dtype=np.uint8) 
im_kp1 = cv2.drawKeypoints(im1,kp1,None) 
im_kp2 = cv2.drawKeypoints(im2,kp2,None) 

bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True) 
matches = bf.match(des1,des2) 

print len(des1) 
# Result : 78 
print len(des2) 
# Result : 71 
print len(matches) 
# Result : 55 

Antwort

0

Da crossCheck=True wird einige der Ergebnisse zu entfernen.

Wenn Sie das Kontroll docs for the BFMatcher() constructor:

crosscheck Wenn es falsch ist, ist dies standardmäßig BFMatcher Verhalten sein wird, wenn es die k nächsten Nachbarn für jede Abfrage Descriptor findet. Wenn crossCheck == true, dann liefert die knnMatch() - Methode mit k = 1 nur Paare (i, j), so dass für den i-ten Query-Deskriptor der j-te Deskriptor in der Matcher-Sammlung der nächste ist und umgekehrt Der BFMatcher gibt nur konsistente Paare zurück. Eine solche Technik erzeugt normalerweise die besten Ergebnisse mit einer minimalen Anzahl von Ausreißern, wenn genügend Übereinstimmungen vorhanden sind. Dies ist eine Alternative zu dem von D. Lowe in SIFT-Papier verwendeten Verhältnistest.

Das liest sich wie es nur die knnMatch() Verfahren beeinflussen, aber die match() Methoden tatsächlich explicitly call knnMatch():

void DescriptorMatcher::match(InputArray queryDescriptors, std::vector<DMatch>& matches, InputArrayOfArrays masks) 
{ 
    CV_INSTRUMENT_REGION() 

    std::vector<std::vector<DMatch> > knnMatches; 
    knnMatch(queryDescriptors, knnMatches, 1, masks, true /*compactResult*/); 
    convertMatches(knnMatches, matches); 
} 

Wenn Sie setzen crossCheck=False (oder geben Sie einfach nicht, dann ist es False durch Standard), dann erhalten Sie

len(query_descriptors) == len(matches) 
Verwandte Themen