Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions glomap/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ set(SOURCES
io/colmap_converter.cc
io/colmap_io.cc
io/pose_io.cc
io/utils.cc
math/gravity.cc
math/rigid3d.cc
math/tree.cc
Expand Down Expand Up @@ -44,6 +45,7 @@ set(HEADERS
io/colmap_converter.h
io/colmap_io.h
io/pose_io.h
io/utils.h
math/gravity.h
math/l1_solver.h
math/rigid3d.h
Expand Down
19 changes: 13 additions & 6 deletions glomap/controllers/track_retriangulation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@ bool RetriangulateTracks(const TriangulatorOptions& options,
std::unordered_map<camera_t, Camera>& cameras,
std::unordered_map<image_t, Image>& images,
std::unordered_map<track_t, Track>& tracks) {
// Collect the registered images
std::unordered_set<std::string> registered_image_names;
for (const auto& [image_id, image] : images) {
if (image.is_registered) {
registered_image_names.insert(image.file_name);
}
}
// Following code adapted from COLMAP
auto database_cache =
colmap::DatabaseCache::Create(database,
options.min_num_matches,
false, // ignore_watermarks
{} // reconstruct all possible images
);
auto database_cache = colmap::DatabaseCache::Create(
database,
options.min_num_matches,
false, // ignore_watermarks
registered_image_names // reconstruct all possible images
);

// Check whether the image is in the database cache. If not, set the image
// as not registered to avoid memory error.
Expand Down
19 changes: 18 additions & 1 deletion glomap/exe/global_mapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "glomap/controllers/option_manager.h"
#include "glomap/io/colmap_io.h"
#include "glomap/io/pose_io.h"
#include "glomap/io/utils.h"
#include "glomap/types.h"

#include <colmap/util/file.h>
Expand All @@ -19,11 +21,16 @@ int RunMapper(int argc, char** argv) {
std::string image_path = "";
std::string constraint_type = "ONLY_POINTS";
std::string output_format = "bin";
std::string image_list_path = "";

OptionManager options;
options.AddRequiredOption("database_path", &database_path);
options.AddRequiredOption("output_path", &output_path);
options.AddDefaultOption("image_path", &image_path);
options.AddDefaultOption("image_list_path",
&image_list_path,
"Path to the image list file, if not provided, "
"all images in the database will be used");
options.AddDefaultOption("constraint_type",
&constraint_type,
"{ONLY_POINTS, ONLY_CAMERAS, "
Expand Down Expand Up @@ -61,14 +68,24 @@ int RunMapper(int argc, char** argv) {
return EXIT_FAILURE;
}

std::unordered_set<std::string> image_filenames;
if (image_list_path != "") {
if (!colmap::ExistsFile(image_list_path)) {
LOG(ERROR) << "`image_list_path` is not a file";
return EXIT_FAILURE;
}
ReadImageList(image_list_path, image_filenames);
}

// Load the database
ViewGraph view_graph;
std::unordered_map<camera_t, Camera> cameras;
std::unordered_map<image_t, Image> images;
std::unordered_map<track_t, Track> tracks;

const colmap::Database database(database_path);
ConvertDatabaseToGlomap(database, view_graph, cameras, images);
ConvertDatabaseToGlomap(
database, view_graph, cameras, images, &image_filenames);

if (view_graph.image_pairs.empty()) {
LOG(ERROR) << "Can't continue without image pairs";
Expand Down
22 changes: 18 additions & 4 deletions glomap/io/colmap_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,13 @@ void ConvertColmapPoints3DToGlomapTracks(

// For ease of debug, go through the database twice: first extract the available
// pairs, then read matches from pairs.
void ConvertDatabaseToGlomap(const colmap::Database& database,
ViewGraph& view_graph,
std::unordered_map<camera_t, Camera>& cameras,
std::unordered_map<image_t, Image>& images) {
void ConvertDatabaseToGlomap(
const colmap::Database& database,
ViewGraph& view_graph,
std::unordered_map<camera_t, Camera>& cameras,
std::unordered_map<image_t, Image>& images,
const std::unordered_set<std::string>* image_filenames) {
bool has_image_filenames = image_filenames && !image_filenames->empty();
// Add the images
std::vector<colmap::Image> images_colmap = database.ReadAllImages();
image_t counter = 0;
Expand All @@ -188,6 +191,11 @@ void ConvertDatabaseToGlomap(const colmap::Database& database,
<< images_colmap.size() << std::flush;
counter++;

if (has_image_filenames &&
image_filenames->find(image.Name()) == image_filenames->end()) {
continue; // Skip images not in the specified set
}

const image_t image_id = image.ImageId();
if (image_id == colmap::kInvalidImageId) continue;
auto ite = images.insert(std::make_pair(
Expand Down Expand Up @@ -239,6 +247,12 @@ void ConvertDatabaseToGlomap(const colmap::Database& database,
colmap::image_t image_id1 = image_pair_colmap.first;
colmap::image_t image_id2 = image_pair_colmap.second;

if (images.find(image_id1) == images.end() ||
images.find(image_id2) == images.end()) {
// If the image is not added to the images map, then skip
continue;
}

colmap::FeatureMatches& feature_matches = all_matches[match_idx].second;

// Initialize the image pair
Expand Down
10 changes: 6 additions & 4 deletions glomap/io/colmap_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ void ConvertColmapPoints3DToGlomapTracks(
const colmap::Reconstruction& reconstruction,
std::unordered_map<track_t, Track>& tracks);

void ConvertDatabaseToGlomap(const colmap::Database& database,
ViewGraph& view_graph,
std::unordered_map<camera_t, Camera>& cameras,
std::unordered_map<image_t, Image>& images);
void ConvertDatabaseToGlomap(
const colmap::Database& database,
ViewGraph& view_graph,
std::unordered_map<camera_t, Camera>& cameras,
std::unordered_map<image_t, Image>& images,
const std::unordered_set<std::string>* image_filenames = nullptr);

} // namespace glomap
23 changes: 19 additions & 4 deletions glomap/io/pose_io.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
namespace glomap {
void ReadRelPose(const std::string& file_path,
std::unordered_map<image_t, Image>& images,
ViewGraph& view_graph) {
ViewGraph& view_graph,
bool editable_images) {
std::unordered_map<std::string, image_t> name_idx;
image_t max_image_id = 0;
for (const auto& [image_id, image] : images) {
Expand Down Expand Up @@ -35,21 +36,28 @@ void ReadRelPose(const std::string& file_path,
std::getline(line_stream, item, ' ');
file2 = item;

bool add_image = true;
if (name_idx.find(file1) == name_idx.end()) {
if (!editable_images) {
add_image = false;
}
max_image_id += 1;
images.insert(
std::make_pair(max_image_id, Image(max_image_id, -1, file1)));
name_idx[file1] = max_image_id;
}
if (name_idx.find(file2) == name_idx.end()) {
if (!editable_images) {
add_image = false;
}
max_image_id += 1;
images.insert(
std::make_pair(max_image_id, Image(max_image_id, -1, file2)));
name_idx[file2] = max_image_id;
}

image_t index1 = name_idx[file1];
image_t index2 = name_idx[file2];
image_t index1 = add_image ? name_idx[file1] : -1;
image_t index2 = add_image ? name_idx[file2] : -1;

image_pair_t pair_id = ImagePair::ImagePairToPairId(index1, index2);

Expand All @@ -64,10 +72,17 @@ void ReadRelPose(const std::string& file_path,
std::getline(line_stream, item, ' ');
pose_rel.translation[i] = std::stod(item);
}
if (!add_image) continue;

counter++;
if (view_graph.image_pairs.find(pair_id) != view_graph.image_pairs.end()) {
// If the pair already exists, update the relative pose
view_graph.image_pairs[pair_id].cam2_from_cam1 = pose_rel;
view_graph.image_pairs[pair_id].is_valid = true;
continue;
}
view_graph.image_pairs.insert(
std::make_pair(pair_id, ImagePair(index1, index2, pose_rel)));
counter++;
}
LOG(INFO) << counter << " relpose are loaded" << std::endl;
}
Expand Down
4 changes: 3 additions & 1 deletion glomap/io/pose_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
namespace glomap {
// Required data structures
// IMAGE_NAME_1 IMAGE_NAME_2 QW QX QY QZ TX TY TZ
// editable_images: where the images can be added if they are not present
void ReadRelPose(const std::string& file_path,
std::unordered_map<image_t, Image>& images,
ViewGraph& view_graph);
ViewGraph& view_graph,
bool editable_images = true);

// Required data structures
// IMAGE_NAME_1 IMAGE_NAME_2 weight
Expand Down
21 changes: 21 additions & 0 deletions glomap/io/utils.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "glomap/io/utils.h"

#include <fstream>

#include "colmap/util/string.h"

namespace glomap {
void ReadImageList(const std::string& file_path,
std::unordered_set<std::string>& image_filenames) {
std::ifstream image_list_file(file_path);
std::string line;
while (std::getline(image_list_file, line)) {
if (!line.empty()) {
colmap::StringTrim(&line);
image_filenames.insert(line);
}
}
image_list_file.close();
}

} // namespace glomap
15 changes: 15 additions & 0 deletions glomap/io/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <string>
#include <unordered_set>

namespace glomap {
// Read a list of image filenames from a file.
// Required data structure:
// IMAGE_NAME_1
// IMAGE_NAME_2
// ...
// IMAGE_NAME_N
void ReadImageList(const std::string& file_path,
std::unordered_set<std::string>& image_filenames);
} // namespace glomap
5 changes: 4 additions & 1 deletion glomap/processors/view_graph_manipulation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ image_t ViewGraphManipulater::EstablishStrongClusters(
StrongClusterCriteria criteria,
double min_thres,
int min_num_images) {
image_t num_img_before = view_graph.KeepLargestConnectedComponents(images);
// Mark all images as registered
for (auto& [image_id, image] : images) {
image.is_registered = true;
}

// Construct the initial cluster by keeping the pairs with weight > min_thres
UnionFind<image_pair_t> uf;
Expand Down
Loading