Skip to content

Commit ce08ebe

Browse files
authored
View graph simplification (colmap#225)
* Update to latest colmap and use L1 solver + union-find from colmap * Simplify view graph * d * d
1 parent ca27e0e commit ce08ebe

File tree

11 files changed

+146
-196
lines changed

11 files changed

+146
-196
lines changed

glomap/estimators/global_rotation_averaging.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ void RotationEstimator::InitializeFromMaximumSpanningTree(
121121

122122
// Directly use the relative pose for estimation rotation
123123
const ImagePair& image_pair = view_graph.image_pairs.at(
124-
ImagePair::ImagePairToPairId(curr, parents[curr]));
124+
colmap::ImagePairToPairId(curr, parents[curr]));
125125
if (image_pair.image_id1 == curr) {
126126
// 1_R_w = 2_R_1^T * 2_R_w
127127
cam_from_worlds[curr].rotation =

glomap/estimators/gravity_refinement.cc

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@ namespace glomap {
99
void GravityRefiner::RefineGravity(const ViewGraph& view_graph,
1010
std::unordered_map<frame_t, Frame>& frames,
1111
std::unordered_map<image_t, Image>& images) {
12-
const std::unordered_map<image_pair_t, ImagePair>& image_pairs =
13-
view_graph.image_pairs;
1412
const std::unordered_map<image_t, std::unordered_set<image_t>>&
15-
adjacency_list = view_graph.GetAdjacencyList();
13+
adjacency_list = view_graph.CreateImageAdjacencyList();
1614
if (adjacency_list.empty()) {
17-
LOG(INFO) << "Adjacency list not established" << std::endl;
15+
LOG(INFO) << "Adjacency list not established";
1816
return;
1917
}
2018

@@ -24,16 +22,16 @@ void GravityRefiner::RefineGravity(const ViewGraph& view_graph,
2422
IdentifyErrorProneGravity(view_graph, frames, images, error_prone_frames);
2523

2624
if (error_prone_frames.empty()) {
27-
LOG(INFO) << "No error prone frames found" << std::endl;
25+
LOG(INFO) << "No error prone frames found";
2826
return;
2927
}
3028
// Get the relevant pair ids for frames
3129
std::unordered_map<frame_t, std::unordered_set<image_pair_t>>
3230
adjacency_list_frames_to_pair_id;
3331
for (auto& [image_id, neighbors] : adjacency_list) {
34-
for (auto neighbor : neighbors) {
32+
for (const auto& neighbor : neighbors) {
3533
adjacency_list_frames_to_pair_id[images[image_id].frame_id].insert(
36-
ImagePair::ImagePairToPairId(image_id, neighbor));
34+
colmap::ImagePairToPairId(image_id, neighbor));
3735
}
3836
}
3937

@@ -59,8 +57,8 @@ void GravityRefiner::RefineGravity(const ViewGraph& view_graph,
5957
int counter = 0;
6058
Eigen::Vector3d gravity = frames[frame_id].gravity_info.GetGravity();
6159
for (const auto& pair_id : neighbors) {
62-
image_t image_id1 = image_pairs.at(pair_id).image_id1;
63-
image_t image_id2 = image_pairs.at(pair_id).image_id2;
60+
const image_t image_id1 = view_graph.image_pairs.at(pair_id).image_id1;
61+
const image_t image_id2 = view_graph.image_pairs.at(pair_id).image_id2;
6462
if (!images.at(image_id1).HasGravity() ||
6563
!images.at(image_id2).HasGravity())
6664
continue;
@@ -82,17 +80,18 @@ void GravityRefiner::RefineGravity(const ViewGraph& view_graph,
8280
// consider a single cost term
8381
if (images.at(image_id1).frame_id == frame_id) {
8482
gravities.emplace_back(
85-
(colmap::Inverse(image_pairs.at(pair_id).cam2_from_cam1 *
83+
(colmap::Inverse(view_graph.image_pairs.at(pair_id).cam2_from_cam1 *
8684
cam1_from_rig1)
8785
.rotation.toRotationMatrix() *
8886
images[image_id2].GetRAlign())
8987
.col(1));
9088
} else if (images.at(image_id2).frame_id == frame_id) {
91-
gravities.emplace_back(((colmap::Inverse(cam2_from_rig2) *
92-
image_pairs.at(pair_id).cam2_from_cam1)
93-
.rotation.toRotationMatrix() *
94-
images[image_id1].GetRAlign())
95-
.col(1));
89+
gravities.emplace_back(
90+
((colmap::Inverse(cam2_from_rig2) *
91+
view_graph.image_pairs.at(pair_id).cam2_from_cam1)
92+
.rotation.toRotationMatrix() *
93+
images[image_id1].GetRAlign())
94+
.col(1));
9695
}
9796

9897
ceres::CostFunction* coor_cost =
@@ -123,9 +122,8 @@ void GravityRefiner::RefineGravity(const ViewGraph& view_graph,
123122
frames[frame_id].gravity_info.SetGravity(gravity);
124123
}
125124
}
126-
std::cout << std::endl;
127125
LOG(INFO) << "Number of rectified frames: " << counter_rect << " / "
128-
<< error_prone_frames.size() << std::endl;
126+
<< error_prone_frames.size();
129127
}
130128

131129
void GravityRefiner::IdentifyErrorProneGravity(
@@ -179,7 +177,6 @@ void GravityRefiner::IdentifyErrorProneGravity(
179177
error_prone_frames.insert(frame_id);
180178
}
181179
}
182-
LOG(INFO) << "Number of error prone frames: " << error_prone_frames.size()
183-
<< std::endl;
180+
LOG(INFO) << "Number of error prone frames: " << error_prone_frames.size();
184181
}
185182
} // namespace glomap

glomap/io/colmap_converter.cc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ void ConvertDatabaseToGlomap(const colmap::Database& database,
361361

362362
// Initialize the image pair
363363
auto ite = image_pairs.insert(
364-
std::make_pair(ImagePair::ImagePairToPairId(image_id1, image_id2),
364+
std::make_pair(colmap::ImagePairToPairId(image_id1, image_id2),
365365
ImagePair(image_id1, image_id2)));
366366
ImagePair& image_pair = ite.first->second;
367367

@@ -419,8 +419,6 @@ void ConvertDatabaseToGlomap(const colmap::Database& database,
419419
}
420420
image_pair.matches.conservativeResize(count, 2);
421421
}
422-
std::cout << std::endl;
423-
424422
LOG(INFO) << "Pairs read done. " << invalid_count << " / "
425423
<< view_graph.image_pairs.size() << " are invalid";
426424
}

glomap/io/pose_io.cc

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void ReadRelPose(const std::string& file_path,
5656
image_t index1 = name_idx[file1];
5757
image_t index2 = name_idx[file2];
5858

59-
image_pair_t pair_id = ImagePair::ImagePairToPairId(index1, index2);
59+
const image_pair_t pair_id = colmap::ImagePairToPairId(index1, index2);
6060

6161
// rotation
6262
Rigid3d pose_rel;
@@ -81,7 +81,7 @@ void ReadRelPose(const std::string& file_path,
8181
}
8282
counter++;
8383
}
84-
LOG(INFO) << counter << " relpose are loaded" << std::endl;
84+
LOG(INFO) << counter << " relative poses are loaded";
8585
}
8686

8787
void ReadRelWeight(const std::string& file_path,
@@ -118,7 +118,7 @@ void ReadRelWeight(const std::string& file_path,
118118
image_t index1 = name_idx[file1];
119119
image_t index2 = name_idx[file2];
120120

121-
image_pair_t pair_id = ImagePair::ImagePairToPairId(index1, index2);
121+
image_pair_t pair_id = colmap::ImagePairToPairId(index1, index2);
122122

123123
if (view_graph.image_pairs.find(pair_id) == view_graph.image_pairs.end())
124124
continue;
@@ -127,7 +127,7 @@ void ReadRelWeight(const std::string& file_path,
127127
view_graph.image_pairs[pair_id].weight = std::stod(item);
128128
counter++;
129129
}
130-
LOG(INFO) << counter << " weights are used are loaded" << std::endl;
130+
LOG(INFO) << counter << " weights are used are loaded";
131131
}
132132

133133
// TODO: now, we only store 1 single gravity per rig.
@@ -172,7 +172,7 @@ void ReadGravity(const std::string& gravity_path,
172172
}
173173
}
174174
}
175-
LOG(INFO) << counter << " images are loaded with gravity" << std::endl;
175+
LOG(INFO) << counter << " images are loaded with gravity";
176176
}
177177

178178
void WriteGlobalRotation(const std::string& file_path,
@@ -185,7 +185,7 @@ void WriteGlobalRotation(const std::string& file_path,
185185
}
186186
}
187187
for (const auto& image_id : existing_images) {
188-
const auto image = images.at(image_id);
188+
const auto& image = images.at(image_id);
189189
if (!image.IsRegistered()) continue;
190190
file << image.file_name;
191191
Rigid3d cam_from_world = image.CamFromWorld();
@@ -205,8 +205,8 @@ void WriteRelPose(const std::string& file_path,
205205
std::map<std::string, image_pair_t> name_pair;
206206
for (const auto& [pair_id, image_pair] : view_graph.image_pairs) {
207207
if (image_pair.is_valid) {
208-
const auto image1 = images.at(image_pair.image_id1);
209-
const auto image2 = images.at(image_pair.image_id2);
208+
const auto& image1 = images.at(image_pair.image_id1);
209+
const auto& image2 = images.at(image_pair.image_id2);
210210
name_pair[image1.file_name + " " + image2.file_name] = pair_id;
211211
}
212212
}
@@ -226,6 +226,6 @@ void WriteRelPose(const std::string& file_path,
226226
file << "\n";
227227
}
228228

229-
LOG(INFO) << name_pair.size() << " relpose are written" << std::endl;
229+
LOG(INFO) << name_pair.size() << " relpose are written";
230230
}
231-
} // namespace glomap
231+
} // namespace glomap

glomap/processors/image_pair_inliers.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,4 @@ void ImagePairsInlierCount(ViewGraph& view_graph,
212212
}
213213
}
214214

215-
} // namespace glomap
215+
} // namespace glomap

glomap/processors/reconstruction_pruning.cc

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ image_t PruneWeaklyConnectedImages(std::unordered_map<frame_t, Frame>& frames,
2323
image_t image_id2 = track.observations[j].first;
2424
frame_t frame_id2 = images[image_id2].frame_id;
2525
if (frame_id1 == frame_id2) continue;
26-
image_pair_t pair_id =
27-
ImagePair::ImagePairToPairId(frame_id1, frame_id2);
26+
const image_pair_t pair_id =
27+
colmap::ImagePairToPairId(frame_id1, frame_id2);
2828
if (pair_covisibility_count.find(pair_id) ==
2929
pair_covisibility_count.end()) {
3030
pair_covisibility_count[pair_id] = 1;
@@ -44,8 +44,7 @@ image_t PruneWeaklyConnectedImages(std::unordered_map<frame_t, Frame>& frames,
4444
// then require each pair to have at least 5 points
4545
if (count >= 5) {
4646
counter++;
47-
image_t image_id1, image_id2;
48-
ImagePair::PairIdToImagePair(pair_id, image_id1, image_id2);
47+
const auto [image_id1, image_id2] = colmap::PairIdToImagePair(pair_id);
4948

5049
if (frame_observation_count[image_id1] < min_num_observations ||
5150
frame_observation_count[image_id2] < min_num_observations)
@@ -76,10 +75,9 @@ image_t PruneWeaklyConnectedImages(std::unordered_map<frame_t, Frame>& frames,
7675

7776
ViewGraph visibility_graph;
7877
for (auto& [pair_id, image_pair] : visibility_graph_frame.image_pairs) {
79-
frame_t frame_id1, frame_id2;
80-
ImagePair::PairIdToImagePair(pair_id, frame_id1, frame_id2);
81-
image_t image_id1 = frame_id_to_begin_img[frame_id1];
82-
image_t image_id2 = frame_id_to_begin_img[frame_id2];
78+
const auto [frame_id1, frame_id2] = colmap::PairIdToImagePair(pair_id);
79+
const image_t image_id1 = frame_id_to_begin_img[frame_id1];
80+
const image_t image_id2 = frame_id_to_begin_img[frame_id2];
8381
visibility_graph.image_pairs.insert(
8482
std::make_pair(pair_id, ImagePair(image_id1, image_id2)));
8583
visibility_graph.image_pairs[pair_id].weight = image_pair.weight;
@@ -96,7 +94,7 @@ image_t PruneWeaklyConnectedImages(std::unordered_map<frame_t, Frame>& frames,
9694
if (image_id == begin_image_id || images.find(image_id) == images.end())
9795
continue;
9896
image_pair_t pair_id =
99-
ImagePair::ImagePairToPairId(begin_image_id, image_id);
97+
colmap::ImagePairToPairId(begin_image_id, image_id);
10098
visibility_graph.image_pairs.insert(
10199
std::make_pair(pair_id, ImagePair(begin_image_id, image_id)));
102100

@@ -132,4 +130,4 @@ image_t PruneWeaklyConnectedImages(std::unordered_map<frame_t, Frame>& frames,
132130
// return visibility_graph.MarkConnectedComponents(images, min_num_images);
133131
}
134132

135-
} // namespace glomap
133+
} // namespace glomap

glomap/processors/relpose_filter.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,4 @@ void RelPoseFilter::FilterInlierRatio(ViewGraph& view_graph,
6464
<< " relative poses with inlier ratio < " << min_inlier_ratio;
6565
}
6666

67-
} // namespace glomap
67+
} // namespace glomap

glomap/processors/view_graph_manipulation.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ image_pair_t ViewGraphManipulater::SparsifyGraph(
1717
// Keep track of chosen edges
1818
std::unordered_set<image_pair_t> chosen_edges;
1919
const std::unordered_map<image_t, std::unordered_set<image_t>>&
20-
adjacency_list = view_graph.GetAdjacencyList();
20+
adjacency_list = view_graph.CreateImageAdjacencyList();
2121

2222
// Here, the average is the mean of the degrees
2323
double average_degree = 0;
@@ -47,6 +47,7 @@ image_pair_t ViewGraphManipulater::SparsifyGraph(
4747
continue;
4848
}
4949

50+
// TODO: Replace rand() with thread-safe random number generator.
5051
if (rand() / double(RAND_MAX) <
5152
(expected_degree * average_degree) / (degree1 * degree2)) {
5253
chosen_edges.insert(pair_id);
@@ -208,9 +209,7 @@ void ViewGraphManipulater::UpdateImagePairsConfig(
208209
// pairs are valid, then set the camera to valid
209210
std::unordered_map<camera_t, bool> camera_validity;
210211
for (auto& [camera_id, counter] : camera_counter) {
211-
if (counter.first == 0) {
212-
camera_validity[camera_id] = false;
213-
} else if (counter.second * 1. / counter.first > 0.5) {
212+
if (counter.second * 1. / counter.first > 0.5) {
214213
camera_validity[camera_id] = true;
215214
} else {
216215
camera_validity[camera_id] = false;

glomap/scene/image_pair.h

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,24 @@
99

1010
namespace glomap {
1111

12-
// FUTURE: add covariance to the relative pose
12+
// TODO: add covariance to the relative pose
1313
struct ImagePair {
14-
ImagePair() : pair_id(-1), image_id1(-1), image_id2(-1) {}
15-
ImagePair(image_t img_id1, image_t img_id2, Rigid3d pose_rel = Rigid3d())
16-
: pair_id(ImagePairToPairId(img_id1, img_id2)),
17-
image_id1(img_id1),
18-
image_id2(img_id2),
19-
cam2_from_cam1(pose_rel) {}
14+
ImagePair()
15+
: image_id1(colmap::kInvalidImageId),
16+
image_id2(colmap::kInvalidImageId),
17+
pair_id(colmap::kInvalidImagePairId) {}
18+
ImagePair(image_t image_id1,
19+
image_t image_id2,
20+
Rigid3d cam2_from_cam1 = Rigid3d())
21+
: image_id1(image_id1),
22+
image_id2(image_id2),
23+
pair_id(colmap::ImagePairToPairId(image_id1, image_id2)),
24+
cam2_from_cam1(cam2_from_cam1) {}
2025

2126
// Ids are kept constant
22-
const image_pair_t pair_id;
2327
const image_t image_id1;
2428
const image_t image_id2;
29+
const image_pair_t pair_id;
2530

2631
// indicator whether the image pair is valid
2732
bool is_valid = true;
@@ -40,7 +45,7 @@ struct ImagePair {
4045
Eigen::Matrix3d H = Eigen::Matrix3d::Zero();
4146

4247
// Relative pose.
43-
Rigid3d cam2_from_cam1;
48+
Rigid3d cam2_from_cam1 = Rigid3d();
4449

4550
// Matches between the two images.
4651
// First column is the index of the feature in the first image.
@@ -49,27 +54,6 @@ struct ImagePair {
4954

5055
// Row index of inliers in the matches matrix.
5156
std::vector<int> inliers;
52-
53-
static inline image_pair_t ImagePairToPairId(const image_t image_id1,
54-
const image_t image_id2);
55-
56-
static inline void PairIdToImagePair(const image_pair_t pair_id,
57-
image_t& image_id1,
58-
image_t& image_id2);
5957
};
6058

61-
image_pair_t ImagePair::ImagePairToPairId(const image_t image_id1,
62-
const image_t image_id2) {
63-
return colmap::ImagePairToPairId(image_id1, image_id2);
64-
}
65-
66-
void ImagePair::PairIdToImagePair(const image_pair_t pair_id,
67-
image_t& image_id1,
68-
image_t& image_id2) {
69-
std::pair<image_t, image_t> image_id_pair =
70-
colmap::PairIdToImagePair(pair_id);
71-
image_id1 = image_id_pair.first;
72-
image_id2 = image_id_pair.second;
73-
}
74-
7559
} // namespace glomap

0 commit comments

Comments
 (0)