Main MRPT website > C++ reference
MRPT logo
descriptor_pairing.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) C++ library |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (C) 2005-2012 University of Malaga |
7  | |
8  | This software was written by the Machine Perception and Intelligent |
9  | Robotics Lab, University of Malaga (Spain). |
10  | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> |
11  | |
12  | This file is part of the MRPT project. |
13  | |
14  | MRPT is free software: you can redistribute it and/or modify |
15  | it under the terms of the GNU General Public License as published by |
16  | the Free Software Foundation, either version 3 of the License, or |
17  | (at your option) any later version. |
18  | |
19  | MRPT is distributed in the hope that it will be useful, |
20  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
21  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22  | GNU General Public License for more details. |
23  | |
24  | You should have received a copy of the GNU General Public License |
25  | along with MRPT. If not, see <http://www.gnu.org/licenses/>. |
26  | |
27  +---------------------------------------------------------------------------+ */
28 
29 #ifndef mrpt_vision_descriptor_pairing_H
30 #define mrpt_vision_descriptor_pairing_H
31 
32 #include <mrpt/vision/types.h>
33 
34 namespace mrpt
35 {
36  namespace vision
37  {
38  using mrpt::math::TPose3D;
41 
42  /** \addtogroup mrptvision_features
43  @{ */
44 
45  /** Search for pairings between two sets of visual descriptors (for now, only SURF
46  * and SIFT features are considered).
47  * Pairings are returned in one of two formats (or both of them simultaneously),
48  * depending on the non-NULL output containers present in the call.
49  *
50  * \code
51  * CFeatureList feats1, feats2;
52  * // Populate feature lists [...]
53  *
54  * // Create kd-tree for SIFT features of "feats2":
55  * TSIFTDescriptorsKDTreeIndex<double> feats2_kdtree(feats2);
56  *
57  * // Search correspondences:
58  * std::vector<vector_size_t> pairings_1_to_multi_2;
59  * std::vector<std::pair<size_t,size_t> > pairings_1_to_2;
60  * mrpt::vision::find_descriptor_pairings(
61  * &pairings_1_to_multi_2, // Can be set to NULL if not needed
62  * &pairings_1_to_2, // Can be set to NULL if not needed
63  * feats1, feats2_kdtree, // The two sets of features
64  * mrpt::vision::descSIFT // Select descriptor to use
65  * // [further optional params]
66  * );
67  * \endcode
68  *
69  * \sa TSIFTDescriptorsKDTreeIndex, TSURFDescriptorsKDTreeIndex
70  */
71  template <class DESCRIPTOR_KDTREE>
73  std::vector<vector_size_t> * pairings_1_to_multi_2,
74  std::vector<std::pair<size_t,size_t> > * pairings_1_to_2,
75  const CFeatureList & feats_img1,
76  const DESCRIPTOR_KDTREE & feats_img2_kdtree,
77  const mrpt::vision::TDescriptorType descriptor = descSIFT,
78  const size_t max_neighbors = 4,
79  const double max_relative_distance = 1.2,
80  const typename DESCRIPTOR_KDTREE::kdtree_t::DistanceType max_distance = std::numeric_limits<typename DESCRIPTOR_KDTREE::kdtree_t::DistanceType>::max()
81  )
82  {
84  ASSERT_ABOVEEQ_(max_neighbors,1)
85  ASSERT_(pairings_1_to_multi_2!=NULL || pairings_1_to_2!=NULL)
86 
87  typedef typename DESCRIPTOR_KDTREE::kdtree_t::ElementType KDTreeElementType; // The expected data type of elements for the kd-tree
88  typedef typename DESCRIPTOR_KDTREE::kdtree_t::DistanceType KDTreeDistanceType;
89 
90  const size_t N=feats_img1.size();
91  if (pairings_1_to_multi_2) pairings_1_to_multi_2->assign(N, vector_size_t()); // Reset output container
92  if (pairings_1_to_2) { pairings_1_to_2->clear(); pairings_1_to_2->reserve(N); }
93 
94  size_t overall_pairs = 0;
95 
96  if (!N) return overall_pairs; // No features -> nothing to do
97 
98  if (descriptor==descSIFT) {
99  ASSERTMSG_(feats_img1[0]->descriptors.hasDescriptorSIFT(), "Request to match SIFT features but feats_img1 has no SIFT descriptors!")
100  ASSERTMSG_(sizeof(KDTreeElementType)==sizeof(feats_img1[0]->descriptors.SIFT[0]),"Incorrect data type kd_tree::ElementType for SIFT (should be uint8_t)")
101  }
102  else if (descriptor==descSURF) {
103  ASSERTMSG_(feats_img1[0]->descriptors.hasDescriptorSURF(), "Request to match SURF features but feats_img1 has no SURF descriptors!")
104  ASSERTMSG_(sizeof(KDTreeElementType)==sizeof(feats_img1[0]->descriptors.SURF[0]),"Incorrect data type kd_tree::ElementType for SURF (should be float)")
105  }
106  else { THROW_EXCEPTION("This function only supports SIFT or SURFT descriptors") }
107 
108  std::vector<size_t> indices(max_neighbors);
109  std::vector<double> distances(max_neighbors);
110 
111  for (size_t i=0;i<N;i++)
112  {
113  const CFeature::TDescriptors &descs = feats_img1[i]->descriptors;
114 
115  const void * ptr_query;
116  if (descriptor==descSIFT) ptr_query = &descs.SIFT[0];
117  else if (descriptor==descSURF) ptr_query = &descs.SURF[0];
118 
119  feats_img2_kdtree.get_kdtree().knnSearch(
120  static_cast<const KDTreeElementType*>( ptr_query ), // Query point
121  max_neighbors, // Number of neigbors
122  &indices[0], &distances[0] // Output
123  );
124 
125  // Include all correspondences below the absolute and the relative threshold (indices comes ordered by distances):
126  const KDTreeDistanceType this_thresh = std::min( max_relative_distance*distances[0], max_distance);
127  for (size_t j=0;j<max_neighbors;j++)
128  {
129  if (distances[j]<=this_thresh) {
130  overall_pairs++;
131  if (pairings_1_to_multi_2) (*pairings_1_to_multi_2)[i].push_back(indices[j]);
132  if (pairings_1_to_2) pairings_1_to_2->push_back(std::make_pair(i,indices[j]));
133  }
134  else break;
135  }
136  }
137  return overall_pairs;
138  MRPT_END
139  }
140 
141  /** @} */
142 
143  }
144 }
145 #endif
146 



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013