34 #include <unordered_set>
43 std::unordered_map<image_pair_t, point2D_t>
45 std::unordered_map<image_pair_t, point2D_t> num_corrs_between_images;
46 num_corrs_between_images.reserve(image_pairs_.size());
47 for (
const auto& image_pair : image_pairs_) {
48 num_corrs_between_images.emplace(image_pair.first,
49 image_pair.second.num_correspondences);
51 return num_corrs_between_images;
55 for (
auto it = images_.begin(); it != images_.end();) {
56 it->second.num_observations = 0;
57 for (
auto& corr : it->second.corrs) {
59 if (corr.size() > 0) {
60 it->second.num_observations += 1;
63 if (it->second.num_observations == 0) {
72 const size_t num_points) {
74 images_[image_id].corrs.resize(num_points);
81 if (image_id1 == image_id2) {
82 std::cout <<
"WARNING: Cannot use self-matches for image_id=" << image_id1
88 struct Image& image1 = images_.at(image_id1);
89 struct Image& image2 = images_.at(image_id2);
92 image1.num_correspondences += matches.size();
93 image2.num_correspondences += matches.size();
99 auto& image_pair = image_pairs_[pair_id];
100 image_pair.num_correspondences +=
static_cast<point2D_t>(matches.size());
107 for (
const auto& match : matches) {
108 const bool valid_idx1 = match.point2D_idx1 < image1.corrs.size();
109 const bool valid_idx2 = match.point2D_idx2 < image2.corrs.size();
111 if (valid_idx1 && valid_idx2) {
112 auto& corrs1 = image1.corrs[match.point2D_idx1];
113 auto& corrs2 = image2.corrs[match.point2D_idx2];
115 const bool duplicate1 =
116 std::find_if(corrs1.begin(), corrs1.end(),
118 return corr.image_id == image_id2;
120 const bool duplicate2 =
121 std::find_if(corrs2.begin(), corrs2.end(),
123 return corr.image_id == image_id1;
126 if (duplicate1 || duplicate2) {
127 image1.num_correspondences -= 1;
128 image2.num_correspondences -= 1;
129 image_pair.num_correspondences -= 1;
131 "WARNING: Duplicate correspondence between "
132 "point2D_idx=%d in image_id=%d and point2D_idx=%d in "
134 match.point2D_idx1, image_id1, match.point2D_idx2,
138 corrs1.emplace_back(image_id2, match.point2D_idx2);
139 corrs2.emplace_back(image_id1, match.point2D_idx1);
142 image1.num_correspondences -= 1;
143 image2.num_correspondences -= 1;
144 image_pair.num_correspondences -= 1;
148 "WARNING: point2D_idx=%d in image_id=%d does not exist",
149 match.point2D_idx1, image_id1)
155 "WARNING: point2D_idx=%d in image_id=%d does not exist",
156 match.point2D_idx2, image_id2)
163 std::vector<CorrespondenceGraph::Correspondence>
166 const size_t transitivity)
const {
167 if (transitivity == 1) {
171 std::vector<Correspondence> found_corrs;
176 found_corrs.emplace_back(image_id, point2D_idx);
178 std::unordered_map<image_t, std::unordered_set<point2D_t>> image_corrs;
179 image_corrs[image_id].insert(point2D_idx);
181 size_t corr_queue_begin = 0;
182 size_t corr_queue_end = found_corrs.size();
184 for (
size_t t = 0; t < transitivity; ++t) {
187 for (
size_t i = corr_queue_begin; i < corr_queue_end; ++i) {
191 const std::vector<Correspondence>& ref_corrs =
196 auto& corr_image_corrs = image_corrs[corr.image_id];
197 if (corr_image_corrs.count(corr.point2D_idx) == 0) {
198 corr_image_corrs.insert(corr.point2D_idx);
199 found_corrs.emplace_back(corr.image_id, corr.point2D_idx);
205 corr_queue_begin = corr_queue_end;
206 corr_queue_end = found_corrs.size();
209 if (corr_queue_begin == corr_queue_end) {
216 if (found_corrs.size() > 1) {
217 found_corrs.front() = found_corrs.back();
219 found_corrs.pop_back();
226 const auto num_correspondences =
229 if (num_correspondences == 0) {
234 found_corrs.reserve(num_correspondences);
236 const struct Image& image1 = images_.at(image_id1);
238 for (
point2D_t point2D_idx1 = 0; point2D_idx1 < image1.corrs.size();
241 if (corr1.image_id == image_id2) {
242 found_corrs.emplace_back(point2D_idx1, corr1.point2D_idx);
252 const struct Image&
image = images_.at(image_id);
253 const std::vector<Correspondence>& corrs =
image.corrs.at(point2D_idx);
254 if (corrs.size() != 1) {
257 const struct Image& other_image = images_.at(corrs[0].image_id);
258 const std::vector<Correspondence>& other_corrs =
259 other_image.corrs.at(corrs[0].point2D_idx);
260 return other_corrs.size() == 1;
std::shared_ptr< core::Tensor > image
bool HasCorrespondences(const image_t image_id, const point2D_t point2D_idx) const
bool ExistsImage(const image_t image_id) const
const std::vector< Correspondence > & FindCorrespondences(const image_t image_id, const point2D_t point2D_idx) const
void AddImage(const image_t image_id, const size_t num_points2D)
FeatureMatches FindCorrespondencesBetweenImages(const image_t image_id1, const image_t image_id2) const
std::vector< Correspondence > FindTransitiveCorrespondences(const image_t image_id, const point2D_t point2D_idx, const size_t transitivity) const
bool IsTwoViewObservation(const image_t image_id, const point2D_t point2D_idx) const
void AddCorrespondences(const image_t image_id1, const image_t image_id2, const FeatureMatches &matches)
std::unordered_map< image_pair_t, point2D_t > NumCorrespondencesBetweenImages() const
static image_pair_t ImagePairToPairId(const image_t image_id1, const image_t image_id2)
QTextStream & endl(QTextStream &stream)
std::string StringPrintf(const char *format,...)
std::vector< FeatureMatch > FeatureMatches