Berkeley SfM
feature_matcher.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, The Regents of the University of California (Regents).
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following
14  * disclaimer in the documentation and/or other materials provided
15  * with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Please contact the author(s) of this library if you have any questions.
34  * Authors: Erik Nelson ( eanelson@eecs.berkeley.edu )
35  * David Fridovich-Keil ( dfk@eecs.berkeley.edu )
36  */
37 
38 #include "feature_matcher.h"
39 
40 namespace bsfm {
41 
42 // Append features from a single image to the list of all image features.
44  const std::vector<Feature>& image_features,
45  const std::vector<Descriptor>& image_descriptors) {
46  image_features_.push_back(image_features);
47  image_descriptors_.push_back(image_descriptors);
48 }
49 
50 // Append features from a set of images to the list of all image features.
52  const std::vector<std::vector<Feature> >& image_features,
53  const std::vector<std::vector<Descriptor> >& image_descriptors) {
54  image_features_.insert(image_features_.end(), image_features.begin(),
55  image_features.end());
56  image_descriptors_.insert(image_descriptors_.end(), image_descriptors.begin(),
57  image_descriptors.end());
58 }
59 
61  PairwiseImageMatchList& image_matches) {
62  // Store the matching options locally.
63  options_ = options;
64 
65  // Iterate over all pairs of images and attempt to match them together by
66  // comparing their features.
67  for (size_t ii = 0; ii < image_features_.size(); ++ii) {
68  // Make sure this image has features.
69  if (image_features_[ii].size() == 0) {
70  continue;
71  }
72  for (size_t jj = ii + 1; jj < image_features_.size(); ++jj) {
73  // Make sure this image has features.
74  if (image_features_[jj].size() == 0) {
75  continue;
76  }
77 
78  // Create an image match object and attempt to match image ii to image jj.
79  PairwiseImageMatch image_match;
80  if (!MatchImagePair(ii, jj, image_match)) {
81  VLOG(1) << "Could not match image " << ii << " to image " << jj << ".";
82  continue;
83  }
84 
85  // If the image match was successful, store it.
86  image_matches.push_back(image_match);
87  }
88  }
89 
90  // Return whether or not we found matches between any of the images.
91  return image_matches.size() > 0;
92 }
93 
95  const std::vector<LightFeatureMatch>& feature_matches_lhs,
96  std::vector<LightFeatureMatch>& feature_matches_rhs) {
97  std::unordered_map<int, int> feature_indices;
98  feature_indices.reserve(feature_matches_lhs.size());
99 
100  // Add all LHS matches to the map.
101  for (const auto& feature_match : feature_matches_lhs) {
102  feature_indices.insert(std::make_pair(feature_match.feature_index1_,
103  feature_match.feature_index2_));
104  }
105 
106  // For each match in the RHS set, search for the same match in the LHS set.
107  // If the match is not symmetric, remove it from the RHS set.
108  auto rhs_iter = feature_matches_rhs.begin();
109  while (rhs_iter != feature_matches_rhs.end()) {
110  const auto& lhs_matched_iter =
111  feature_indices.find(rhs_iter->feature_index2_);
112 
113  // If a symmetric match is found, keep it in the RHS set.
114  if (lhs_matched_iter != feature_indices.end()) {
115  if (lhs_matched_iter->second == rhs_iter->feature_index1_) {
116  ++rhs_iter;
117  continue;
118  }
119  }
120 
121  // Remove the non-symmetric match and continue on.
122  feature_matches_rhs.erase(rhs_iter);
123  }
124 }
125 
126 } //\namespace bsfm
virtual bool MatchImages(const FeatureMatcherOptions &options, PairwiseImageMatchList &image_matches)
virtual void SymmetricMatches(const std::vector< LightFeatureMatch > &feature_matches_lhs, std::vector< LightFeatureMatch > &feature_matches_rhs)
std::vector< std::vector< Feature > > image_features_
virtual bool MatchImagePair(int image_index1, int image_index2, PairwiseImageMatch &image_match)=0
std::vector< PairwiseImageMatch > PairwiseImageMatchList
virtual void AddImageFeatures(const std::vector< Feature > &image_features, const std::vector< Descriptor > &image_descriptors)
Definition: camera.cpp:50
std::vector< std::vector< Descriptor > > image_descriptors_
FeatureMatcherOptions options_