40 throw std::runtime_error(
"Unhandled matcher type");
47 if (viewports ==
nullptr)
48 throw std::invalid_argument(
"Viewports must not be null");
50 this->viewports = viewports;
51 this->matcher->init(viewports);
54 for (std::size_t i = 0; i < viewports->size(); i++)
55 viewports->at(i).features.clear_descriptors();
61 if (this->viewports ==
nullptr)
62 throw std::runtime_error(
"Viewports must not be null");
64 std::size_t num_viewports = this->viewports->size();
65 std::size_t num_pairs = num_viewports * (num_viewports - 1) / 2;
66 std::size_t num_done = 0;
68 if (this->progress !=
nullptr)
74#pragma omp parallel for schedule(dynamic)
75 for (std::size_t i = 0; i < num_pairs; ++i)
80 if (this->progress !=
nullptr)
83 float percent = (num_done * 1000 / num_pairs) / 10.0f;
84 std::cout <<
"\rMatching pair " << num_done <<
" of "
85 << num_pairs <<
" (" << percent <<
"%)..." << std::flush;
88 int const view_1_id = (int)(0.5 + std::sqrt(0.25 + 2.0 * i));
89 int const view_2_id = (int)i - view_1_id * (view_1_id - 1) / 2;
91 && view_2_id + this->opts.match_num_previous_frames < view_1_id)
94 FeatureSet const& view_1 = this->viewports->at(view_1_id).features;
95 FeatureSet const& view_2 = this->viewports->at(view_2_id).features;
101 std::stringstream message;
103 this->two_view_matching(view_1_id, view_2_id, &matches, message);
109 std::cout <<
"\rPair (" << view_1_id <<
","
110 << view_2_id <<
") rejected, "
111 << message.str() << std::endl;
123 pairwise_matching->push_back(matching);
124 std::cout <<
"\rPair (" << view_1_id <<
","
125 << view_2_id <<
") matched, " << matching.
matches.size()
126 <<
" inliers, took " << matching_time <<
" ms." << std::endl;
130 std::cout <<
"\rFound a total of " << pairwise_matching->size()
131 <<
" matching image pairs." << std::endl;
135Matching::two_view_matching (
int view_1_id,
int view_2_id,
138 FeatureSet const& view_1 = this->viewports->at(view_1_id).features;
139 FeatureSet const& view_2 = this->viewports->at(view_2_id).features;
145 int const num_matches = this->matcher->pairwise_match_lowres(view_1_id,
149 message <<
"only " << num_matches
151 <<
" low-res matches.";
158 this->matcher->pairwise_match(view_1_id, view_2_id, &matching_result);
163 if (num_matches < min_matches_thres)
165 message <<
"matches below threshold of "
166 << min_matches_thres <<
".";
174 std::vector<int>
const& m12 = matching_result.
matches_1_2;
175 for (std::size_t i = 0; i < m12.size(); ++i)
185 unfiltered_matches.push_back(match);
186 unfiltered_indices.push_back(std::make_pair(i, m12[i]));
195 ransac.estimate(unfiltered_matches, &ransac_result);
196 num_inliers = ransac_result.
inliers.size();
201 if (num_inliers < min_inlier_thres)
203 message <<
"inliers below threshold of "
204 << min_inlier_thres <<
".";
210 matches->reserve(num_inliers);
211 for (
int i = 0; i < num_inliers; ++i)
213 int const inlier_id = ransac_result.
inliers[i];
214 matches->push_back(unfiltered_indices[inlier_id]);
The FeatureSet holds per-feature information for a single view, and allows to transparently compute a...
std::vector< math::Vec2f > positions
Per-feature image position.
static int count_consistent_matches(Result const &matches)
Function that counts the number of valid matches.
RANSAC pose estimation from noisy 2D-2D image correspondences.
void init(ViewportList *viewports)
Initialize matching by passing features to the matcher for preprocessing.
void compute(PairwiseMatching *pairwise_matching)
Computes the pairwise matching between all pairs of views.
@ MATCHER_CASCADE_HASHING
Cross-platform high-resolution real-time timer.
std::size_t get_elapsed(void) const
Returns the milli seconds since last reset.
std::vector< Viewport > ViewportList
The list of all viewports considered for bundling.
std::vector< TwoViewMatching > PairwiseMatching
The matching result between several pairs of views.
std::vector< CorrespondenceIndex > CorrespondenceIndices
A list of all matching feature pairs in two images.
std::vector< Correspondence2D2D > Correspondences2D2D
void swap(mve::Image< T > &a, mve::Image< T > &b)
Specialization of std::swap for efficient image swapping.
#define SFM_BUNDLER_NAMESPACE_END
#define SFM_BUNDLER_NAMESPACE_BEGIN
#define SFM_NAMESPACE_END
#define SFM_NAMESPACE_BEGIN
Two image coordinates which correspond to each other in terms of observing the same point in the scen...
Feature matching result reported as two lists, each with indices in the other set.
std::vector< int > matches_1_2
std::vector< int > inliers
The indices of inliers in the correspondences which led to the homography matrix.
Options for feature matching.
int min_matching_inliers
Minimum number of matching features after RANSAC.
int min_feature_matches
Minimum number of matching features before RANSAC.
int min_lowres_matches
Minimum number of matches from low-res matching.
int match_num_previous_frames
Only match to a few previous frames.
MatcherType matcher_type
Matcher type.
bool use_lowres_matching
Perform low-resolution matching to reject unlikely pairs.
sfm::RansacFundamental::Options ransac_opts
Options for RANSAC computation of the fundamental matrix.
int num_lowres_features
Number of features used for low-res matching.
The matching result between two views.
CorrespondenceIndices matches