Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reconstruction - Since hloc v1.3, largest model data is sometimes not selected #422

Open
ricmatsui opened this issue Sep 8, 2024 · 0 comments

Comments

@ricmatsui
Copy link

As part of run_reconstruction, the data for images.bin, cameras.bin, and points3D.bin for the largest reconstruction is supposed to be moved to sfm_dir. However, this does not happen reliably when COLMAP produces multiple models.

This is because the models in the numbered folders created by COLMAP (models/0, models/1, etc.) are not guaranteed to be in the same order as the reconstructions list returned by COLMAP.

COLMAP numbers the folders based on the count of points3D so that the folder 0 always has the model with the largest number of points and this is different than the order of the reconstructions list: https://github.com/colmap/colmap/blob/db14f5c59bdaa5239b804ff4623f2fb8e5bb2a46/src/colmap/scene/reconstruction_manager.cc#L60-L83

void ReconstructionManager::Write(const std::string& path) const {
  std::vector<std::pair<size_t, size_t>> recon_sizes(reconstructions_.size());
  for (size_t i = 0; i < reconstructions_.size(); ++i) {
    recon_sizes[i] = std::make_pair(i, reconstructions_[i]->NumPoints3D());
  }
  std::sort(recon_sizes.begin(),
            recon_sizes.end(),
            [](const std::pair<size_t, size_t>& first,
               const std::pair<size_t, size_t>& second) {
              return first.second > second.second;
            });


  for (size_t i = 0; i < reconstructions_.size(); ++i) {
    const std::string reconstruction_path = JoinPaths(path, std::to_string(i));
    CreateDirIfNotExists(reconstruction_path);
    reconstructions_[recon_sizes[i].first]->Write(reconstruction_path);
  }
}

This difference causes an issue in run_reconstruction where the data that is moved does not correspond to the model of the largest_index:

for filename in ["images.bin", "cameras.bin", "points3D.bin"]:
if (sfm_dir / filename).exists():
(sfm_dir / filename).unlink()
shutil.move(str(models_path / str(largest_index) / filename), str(sfm_dir))
return reconstructions[largest_index]

Forcing largest_index to always be 0 resolves the issue, but is different behavior than before.

It looks like this issue was introduced as part of hloc 1.3 because before hloc 1.3, the logic involved iterating directly over the model folders 55e6cde#diff-1415a09ff92c2b9e2091340b072a454b63b9b7422a63f363dc6c2dcce7349769:

models = list(models_path.iterdir())
if len(models) == 0:
logging.error('Could not reconstruct any model!')
return None
logging.info(f'Reconstructed {len(models)} models.')
largest_model = None
largest_model_num_images = 0
for model in models:
num_images = len(read_cameras_binary(str(model / 'cameras.bin')))
if num_images > largest_model_num_images:
largest_model = model
largest_model_num_images = num_images
assert largest_model_num_images > 0
logging.info(f'Largest model is #{largest_model.name} '
f'with {largest_model_num_images} images.')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant