diff --git a/skimage/feature/match.py b/skimage/feature/match.py index ccd8c035..5cb1a5ed 100644 --- a/skimage/feature/match.py +++ b/skimage/feature/match.py @@ -3,7 +3,7 @@ from scipy.spatial.distance import cdist def match_descriptors(descriptors1, descriptors2, metric=None, p=2, - threshold=0, cross_check=True): + max_distance=np.inf, cross_check=True): """Brute-force matching of descriptors. For each descriptor in the first set this matcher finds the closest @@ -24,7 +24,7 @@ def match_descriptors(descriptors1, descriptors2, metric=None, p=2, distance is used for binary descriptors automatically. p : int The p-norm to apply for ``metric='minkowski'``. - threshold : float + max_distance : float Maximum allowed distance between descriptors of two keypoints in separate images to be regarded as a match. cross_check : bool @@ -62,4 +62,9 @@ def match_descriptors(descriptors1, descriptors2, metric=None, p=2, indices1 = indices1[mask] indices2 = indices2[mask] - return np.column_stack((indices1, indices2)) + matches = np.column_stack((indices1, indices2)) + + if max_distance < np.inf: + matches = matches[distances[indices1, indices2] < max_distance] + + return matches diff --git a/skimage/feature/tests/test_match.py b/skimage/feature/tests/test_match.py index f9496c0c..1b0a622f 100644 --- a/skimage/feature/tests/test_match.py +++ b/skimage/feature/tests/test_match.py @@ -44,8 +44,7 @@ def test_binary_descriptors_lena_rotation_crosscheck_false(): extractor.extract(rotated_img, keypoints2) descriptors2 = extractor.descriptors - matches = match_descriptors(descriptors1, descriptors2, threshold=0.13, - cross_check=False) + matches = match_descriptors(descriptors1, descriptors2, cross_check=False) exp_matches1 = np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -78,8 +77,7 @@ def test_binary_descriptors_lena_rotation_crosscheck_true(): extractor.extract(rotated_img, keypoints2) descriptors2 = extractor.descriptors - matches = match_descriptors(descriptors1, descriptors2, threshold=0.13, - cross_check=True) + matches = match_descriptors(descriptors1, descriptors2, cross_check=True) exp_matches1 = np.array([ 0, 1, 2, 4, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 19, 20, 21, 24, 26, 27, 28, 29, 30, 35, @@ -91,6 +89,32 @@ def test_binary_descriptors_lena_rotation_crosscheck_true(): assert_equal(matches[:, 1], exp_matches2) +def test_max_distance(): + descs1 = np.zeros((10, 128)) + descs2 = np.zeros((15, 128)) + + descs1[0, :] = 1 + + matches = match_descriptors(descs1, descs2, metric='euclidean', + max_distance=0.1, cross_check=False) + assert len(matches) == 9 + + matches = match_descriptors(descs1, descs2, metric='euclidean', + max_distance=np.sqrt(128.1), + cross_check=False) + assert len(matches) == 10 + + matches = match_descriptors(descs1, descs2, metric='euclidean', + max_distance=0.1, + cross_check=True) + assert_equal(matches, [[1, 0]]) + + matches = match_descriptors(descs1, descs2, metric='euclidean', + max_distance=np.sqrt(128.1), + cross_check=True) + assert_equal(matches, [[1, 0]]) + + if __name__ == '__main__': from numpy import testing testing.run_module_suite()