Loading autocnet/matcher/matcher.py +15 −6 Original line number Diff line number Diff line Loading @@ -11,7 +11,9 @@ DEFAULT_FLANN_PARAMETERS = dict(algorithm=FLANN_INDEX_KDTREE, class FlannMatcher(object): """ A wrapper to the OpenCV Flann based matcher class that adds metadata tracking attributes and methods. metadata tracking attributes and methods. This takes arbitrary descriptors and so should be available for use with any descriptor data stored as an ndarray. Attributes ---------- Loading Loading @@ -51,7 +53,7 @@ class FlannMatcher(object): """ self._flann_matcher.train() def query(self, descriptor, k=3): def query(self, descriptor, k=3, self_neighbor=True): """ Parameters Loading @@ -62,18 +64,25 @@ class FlannMatcher(object): k : int The number of nearest neighbors to search for self_neighbor : bool If the query descriptor is also a member of the train descriptors, default True Returns ------- matched : dataframe containing matched points """ idx = 0 if self_neighbor: idx = 1 matches = self._flann_matcher.knnMatch(descriptor, k=k) matched = [] for m in matches: matched.append((self.image_indices[m[1].imgIdx], m[1].queryIdx, m[1].trainIdx, m[1].distance)) for i in m[idx:]: matched.append((self.image_indices[i.imgIdx], i.queryIdx, i.trainIdx, i.distance)) return pd.DataFrame(matched, columns=['matched_to', 'queryIdx', 'trainIdx', 'distance']) autocnet/matcher/tests/test_matcher.py +19 −2 Original line number Diff line number Diff line Loading @@ -22,9 +22,8 @@ class TestMatcher(unittest.TestCase): self.fd['AS15-M-0296_SML.png'] = sift.detectAndCompute(im1, None) self.fd['AS15-M-0297_SML.png'] = sift.detectAndCompute(im2, None) print(dir(self.fd)) def test_flann_match_two_images(self): def test_flann_match_k_eq_2(self): fmatcher = matcher.FlannMatcher() truth_image_indices = {} counter = 0 Loading @@ -44,6 +43,24 @@ class TestMatcher(unittest.TestCase): distance = matched['distance'] self.assertFalse(distance[distance == 0].any()) def test_flann_match_k_eq_3(self): fmatcher = matcher.FlannMatcher() truth_image_indices = {} counter = 0 for imageid, (keypoint, descriptor) in self.fd.items(): truth_image_indices[counter] = imageid fmatcher.add(descriptor, imageid) counter += 1 self.assertEqual(truth_image_indices, fmatcher.image_indices) fmatcher.train() matched = fmatcher.query(self.fd['AS15-M-0296_SML.png'][1], k=3) self.assertEqual(20, len(matched)) # Check that self neighbors are being omitted distance = matched['distance'] self.assertFalse(distance[distance == 0].any()) def tearDown(self): pass No newline at end of file Loading
autocnet/matcher/matcher.py +15 −6 Original line number Diff line number Diff line Loading @@ -11,7 +11,9 @@ DEFAULT_FLANN_PARAMETERS = dict(algorithm=FLANN_INDEX_KDTREE, class FlannMatcher(object): """ A wrapper to the OpenCV Flann based matcher class that adds metadata tracking attributes and methods. metadata tracking attributes and methods. This takes arbitrary descriptors and so should be available for use with any descriptor data stored as an ndarray. Attributes ---------- Loading Loading @@ -51,7 +53,7 @@ class FlannMatcher(object): """ self._flann_matcher.train() def query(self, descriptor, k=3): def query(self, descriptor, k=3, self_neighbor=True): """ Parameters Loading @@ -62,18 +64,25 @@ class FlannMatcher(object): k : int The number of nearest neighbors to search for self_neighbor : bool If the query descriptor is also a member of the train descriptors, default True Returns ------- matched : dataframe containing matched points """ idx = 0 if self_neighbor: idx = 1 matches = self._flann_matcher.knnMatch(descriptor, k=k) matched = [] for m in matches: matched.append((self.image_indices[m[1].imgIdx], m[1].queryIdx, m[1].trainIdx, m[1].distance)) for i in m[idx:]: matched.append((self.image_indices[i.imgIdx], i.queryIdx, i.trainIdx, i.distance)) return pd.DataFrame(matched, columns=['matched_to', 'queryIdx', 'trainIdx', 'distance'])
autocnet/matcher/tests/test_matcher.py +19 −2 Original line number Diff line number Diff line Loading @@ -22,9 +22,8 @@ class TestMatcher(unittest.TestCase): self.fd['AS15-M-0296_SML.png'] = sift.detectAndCompute(im1, None) self.fd['AS15-M-0297_SML.png'] = sift.detectAndCompute(im2, None) print(dir(self.fd)) def test_flann_match_two_images(self): def test_flann_match_k_eq_2(self): fmatcher = matcher.FlannMatcher() truth_image_indices = {} counter = 0 Loading @@ -44,6 +43,24 @@ class TestMatcher(unittest.TestCase): distance = matched['distance'] self.assertFalse(distance[distance == 0].any()) def test_flann_match_k_eq_3(self): fmatcher = matcher.FlannMatcher() truth_image_indices = {} counter = 0 for imageid, (keypoint, descriptor) in self.fd.items(): truth_image_indices[counter] = imageid fmatcher.add(descriptor, imageid) counter += 1 self.assertEqual(truth_image_indices, fmatcher.image_indices) fmatcher.train() matched = fmatcher.query(self.fd['AS15-M-0296_SML.png'][1], k=3) self.assertEqual(20, len(matched)) # Check that self neighbors are being omitted distance = matched['distance'] self.assertFalse(distance[distance == 0].any()) def tearDown(self): pass No newline at end of file