Ask Your Question

Brute-force matching with crosscheck do not output closet couple

asked 2018-06-01 02:14:46 -0500

updated 2018-06-01 02:40:11 -0500

berak gravatar image

HI, I try to re-implement Brute-force matching ORB with crosscheck: I used: BFMatcher matcher = BFMatcher(cv::NORM_HAMMING, true); In the document of opencv said:

Second param is boolean variable, crossCheck which is false by default. If it is true, Matcher returns only those matches with value (i,j) such that i-th descriptor in set A has j-th descriptor in set B as the best match and vice-versa. That is, the two features in both sets should match each other.

But when I printed out the results and checked it there are exist value(i, j) j-th in B closest with i-th in A but i-th in A do not closest with j-th in B. For example: opencv bfmatch ouput a match couple is: i-th = 9 j-th=5 distance = 18. but I check j-th = 5 in B set closest with i-th = 9 in A set but not vice-versa.

Do anyone have experience with this problem of BFMatch of opencv, or Do I misunderstood something here?

edit retag flag offensive close merge delete


i removed your (useless here) screenshot.

please be so kind, and edit your question again, and add a text version of your console output instead, thank you !

berak gravatar imageberak ( 2018-06-01 02:35:55 -0500 )edit

Is this the same issue as I have with this code snippet?

import numpy as np
import cv2

queries = np.array([[1, 1, 0], [1, 1, 1]], dtype=np.uint8)
trains = np.array([[1, 1, 1], [0, 0, 0]], dtype=np.uint8)

for si, query in enumerate(queries):
    for ti, train in enumerate(trains):
        print('%d -> %d: %d' % (si, ti, cv2.norm(query, train, cv2.NORM_HAMMING)))

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.knnMatch(query, trains, k=1)
for match in matches:
    if match:
        print('%d -> %d: %f' % (match[0].queryIdx, match[0].trainIdx, match[0].distance))

with output

0 -> 0: 1
0 -> 1: 2
1 -> 0: 0
1 -> 1: 3
0 -> 1: 2.0 <= NOT EXPECTED
1 -> 0: 0.0
crogre gravatar imagecrogre ( 2018-06-26 00:49:59 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2018-06-01 02:44:44 -0500

berak gravatar image

updated 2018-06-01 06:28:13 -0500

your results may astonish you, but they're perfectly reasonable.

"closest distance" is not nessecarily reciprocal, see here:

A         B   C       D             E

D's closest neighbour is C, but C's closest neighbour is B, not D.

edit flag offensive delete link more


I don't think it's reasonable. With crossCheck=True, the D->C match should not be included, but OP says it is (if I understand correctly). With crossCheck, only B<->C should be included, without, A->B, B->C, C->B, D->C, E->D, right?

crogre gravatar imagecrogre ( 2018-06-26 00:58:19 -0500 )edit

Question Tools



Asked: 2018-06-01 02:14:46 -0500

Seen: 359 times

Last updated: Jun 01 '18