47 template <
class DESCRIPTOR_KDTREE>
49 std::vector<std::vector<size_t>>* pairings_1_to_multi_2,
50 std::vector<std::pair<size_t, size_t>>* pairings_1_to_2,
51 const CFeatureList& feats_img1,
const DESCRIPTOR_KDTREE& feats_img2_kdtree,
53 const size_t max_neighbors = 4,
const double max_relative_distance = 1.2,
54 const typename DESCRIPTOR_KDTREE::kdtree_t::DistanceType max_distance =
56 typename DESCRIPTOR_KDTREE::kdtree_t::DistanceType>::max())
60 ASSERT_(pairings_1_to_multi_2 !=
nullptr || pairings_1_to_2 !=
nullptr);
63 using KDTreeElementType =
typename DESCRIPTOR_KDTREE::kdtree_t::ElementType;
64 using KDTreeDistanceType =
65 typename DESCRIPTOR_KDTREE::kdtree_t::DistanceType;
67 const size_t N = feats_img1.
size();
68 if (pairings_1_to_multi_2)
69 pairings_1_to_multi_2->assign(
70 N, std::vector<size_t>());
73 pairings_1_to_2->clear();
74 pairings_1_to_2->reserve(N);
77 size_t overall_pairs = 0;
79 if (!N)
return overall_pairs;
84 feats_img1[0].descriptors.hasDescriptorSIFT(),
85 "Request to match SIFT features but feats_img1 has no SIFT "
88 sizeof(KDTreeElementType) ==
89 sizeof((*feats_img1[0].descriptors.SIFT)[0]),
90 "Incorrect data type kd_tree::ElementType for SIFT (should be "
96 feats_img1[0].descriptors.hasDescriptorSURF(),
97 "Request to match SURF features but feats_img1 has no SURF "
100 sizeof(KDTreeElementType) ==
101 sizeof((*feats_img1[0].descriptors.SURF)[0]),
102 "Incorrect data type kd_tree::ElementType for SURF (should be "
108 "This function only supports SIFT or SURFT descriptors");
111 std::vector<size_t> indices(max_neighbors);
112 std::vector<double> distances(max_neighbors);
114 for (
size_t i = 0; i < N; i++)
118 const void* ptr_query;
120 ptr_query = &(*descs.
SIFT)[0];
122 ptr_query = &(*descs.
SURF)[0];
124 feats_img2_kdtree.get_kdtree().knnSearch(
125 static_cast<const KDTreeElementType*
>(ptr_query),
127 &indices[0], &distances[0]
132 const KDTreeDistanceType this_thresh =
133 std::min(max_relative_distance * distances[0], max_distance);
134 for (
size_t j = 0; j < max_neighbors; j++)
136 if (distances[j] <= this_thresh)
139 if (pairings_1_to_multi_2)
140 (*pairings_1_to_multi_2)[i].push_back(indices[j]);
142 pairings_1_to_2->push_back(std::make_pair(i, indices[j]));
148 return overall_pairs;