If I understand the purpose and documentation of the brute force matcher with cross check enabled, I don't think it works as expected. See the example code below
import numpy
import cv2
sources = numpy.array([[1, 1, 0], [1, 1, 1]], dtype=numpy.uint8)
targets = numpy.array([[1, 1, 1], [0, 0, 0]], dtype=numpy.uint8)
for si, source in enumerate(sources):
for ti, target in enumerate(targets):
print('%d -> %d: %d' % (si, ti, cv2.norm(source, target, cv2.NORM_HAMMING)))
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.knnMatch(sources, targets, k=1)
print('-- crosscheck=True')
for match in matches:
if match:
print('%d -> %d: %f' % (match[0].queryIdx, match[0].trainIdx, match[0].distance))
bf_nocc = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=False)
matches_nocc = bf.knnMatch(sources, targets, k=1)
print('-- crosscheck=False')
for match in matches_nocc:
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
-- crossCheck=True
0 -> 1: 2.000000
1 -> 0: 0.000000
-- crossCheck=False
0 -> 0: 1.000000
1 -> 0: 0.000000
I would expect the crossCheck to remove the 0 -> 1 match since source 0 is closest to target 0. Have I misunderstood how the cross check is supposed to work or is this an issue with the matcher?