DsfTrackGenerator.cpp
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
20 
21 #include <algorithm>
22 #include <iostream>
23 #include <iomanip>
24 
25 namespace gtsam {
26 
27 namespace gtsfm {
28 
30 
32 static DSFMapIndexPair generateDSF(const MatchIndicesMap& matches) {
33  DSFMapIndexPair dsf;
34 
35  for (const auto& kv : matches) {
36  const auto pair_indices = kv.first;
37  const auto corr_indices = kv.second;
38 
39  // Image pair is (i1,i2).
40  size_t i1 = pair_indices.first;
41  size_t i2 = pair_indices.second;
42  size_t m = static_cast<size_t>(corr_indices.rows());
43  for (size_t k = 0; k < m; k++) {
44  // Measurement indices are found in a single matrix row, as (k1,k2).
45  size_t k1 = corr_indices(k, 0), k2 = corr_indices(k, 1);
46  // Unique key for DSF is (i,k), representing keypoint index in an image.
47  dsf.merge({i1, k1}, {i2, k2});
48  }
49  }
50 
51  return dsf;
52 }
53 
55 static SfmTrack2d trackFromIndexPairs(const std::set<IndexPair>& index_pair_set,
56  const KeypointsVector& keypoints) {
57  // Initialize track from measurements.
58  SfmTrack2d track2d;
59 
60  for (const auto& index_pair : index_pair_set) {
61  // Camera index is represented by i, and measurement index is
62  // represented by k.
63  size_t i = index_pair.i();
64  size_t k = index_pair.j();
65  // Add measurement to this track.
66  track2d.addMeasurement(i, keypoints[i].coordinates.row(k));
67  }
68 
69  return track2d;
70 }
71 
73 static std::vector<SfmTrack2d> tracksFromDSF(const DSFMapIndexPair& dsf,
74  const KeypointsVector& keypoints) {
75  const std::map<IndexPair, std::set<IndexPair> > key_sets = dsf.sets();
76 
77  // Return immediately if no sets were found.
78  if (key_sets.empty()) return {};
79 
80  // Create a list of tracks.
81  // Each track will be represented as a list of (camera_idx, measurements).
82  std::vector<SfmTrack2d> tracks2d;
83  for (const auto& kv : key_sets) {
84  // Initialize track from measurements.
85  SfmTrack2d track2d = trackFromIndexPairs(kv.second, keypoints);
86  tracks2d.emplace_back(track2d);
87  }
88  return tracks2d;
89 }
90 
103 std::vector<SfmTrack2d> tracksFromPairwiseMatches(
104  const MatchIndicesMap& matches, const KeypointsVector& keypoints,
105  bool verbose) {
106  // Generate the DSF to form tracks.
107  if (verbose) std::cout << "[SfmTrack2d] Starting Union-Find..." << std::endl;
108  DSFMapIndexPair dsf = generateDSF(matches);
109  if (verbose) std::cout << "[SfmTrack2d] Union-Find Complete" << std::endl;
110 
111  std::vector<SfmTrack2d> tracks2d = tracksFromDSF(dsf, keypoints);
112 
113  // Filter out erroneous tracks that had repeated measurements within the
114  // same image. This is an expected result from an incorrect correspondence
115  // slipping through.
116  std::vector<SfmTrack2d> validTracks;
117  std::copy_if(
118  tracks2d.begin(), tracks2d.end(), std::back_inserter(validTracks),
119  [](const SfmTrack2d& track2d) { return track2d.hasUniqueCameras(); });
120 
121  if (verbose) {
122  size_t erroneous_track_count = tracks2d.size() - validTracks.size();
123  double erroneous_percentage = static_cast<float>(erroneous_track_count) /
124  static_cast<float>(tracks2d.size()) * 100;
125 
126  std::cout << std::fixed << std::setprecision(2);
127  std::cout << "DSF Union-Find: " << erroneous_percentage;
128  std::cout << "% of tracks discarded from multiple obs. in a single image."
129  << std::endl;
130  }
131 
132  // TODO(johnwlambert): return the Transitivity failure percentage here.
133  return tracks2d;
134 }
135 
136 } // namespace gtsfm
137 
138 } // namespace gtsam
Matrix3f m
void merge(const KEY &x, const KEY &y)
Merge two sets.
Definition: DSFMap.h:87
DSFMap< IndexPair > DSFMapIndexPair
std::map< IndexPair, CorrespondenceIndices > MatchIndicesMap
static DSFMapIndexPair generateDSF(const MatchIndicesMap &matches)
Generate the DSF to form tracks.
static SfmTrack2d trackFromIndexPairs(const std::set< IndexPair > &index_pair_set, const KeypointsVector &keypoints)
Generate a single track from a set of index pairs.
Identifies connected components in the keypoint matches graph.
static std::vector< SfmTrack2d > tracksFromDSF(const DSFMapIndexPair &dsf, const KeypointsVector &keypoints)
Generate tracks from the DSF.
std::vector< SfmTrack2d > tracksFromPairwiseMatches(const MatchIndicesMap &matches, const KeypointsVector &keypoints, bool verbose)
Creates a list of tracks from 2d point correspondences.
void addMeasurement(size_t idx, const gtsam::Point2 &m)
Add measurement (camera_idx, Point2) to track.
Definition: SfmTrack.h:64
Track containing 2D measurements associated with a single 3D point. Note: Equivalent to gtsam...
Definition: SfmTrack.h:42
std::vector< Keypoints > KeypointsVector
traits
Definition: chartTesting.h:28
std::map< KEY, Set > sets() const
return all sets, i.e. a partition of all elements
Definition: DSFMap.h:105


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:34:11