In [ ]:
%load_ext autoreload
%autoreload 2

from pathlib import Path

from hloc import extract_features, match_features, reconstruction, visualization

Setup

In this notebook, we will run SfM reconstruction from scratch on a set of images. We choose the South-Building dataset - we will download it later. First, we define some paths.

In [ ]:
dataset = Path('datasets/sfm_South-Building/')
images = dataset / 'South-Building/images/'

outputs = Path('outputs/sfm/')
sfm_pairs = outputs / 'pairs-exhaustive.txt'  # exhaustive matching
sfm_dir = outputs / 'sfm_superpoint+superglue'

feature_conf = extract_features.confs['superpoint_aachen']
matcher_conf = match_features.confs['superglue']

features = feature_conf['output']
feature_file = f"{features}.h5"
match_file = f"{features}_{matcher_conf['output']}_{sfm_pairs.stem}.h5"

Download the dataset

The dataset is simply a set of images. The intrinsic parameters will be extracted from the EXIF data, and refined with SfM.

In [ ]:
%%bash -s "$dataset"
wget http://cvg.ethz.ch/research/local-feature-evaluation/South-Building.zip -P $1
unzip datasets/South-Building.zip -d $1

Extract local features

In [ ]:
extract_features.main(feature_conf, images, outputs)

Exhaustive matching

Since the dataset is small, we can match all $\frac{n(n-1)}{2}$ images pairs. To do so, we pass the argument exhaustive=True and make sure that the pair file does not exist yet. If your dataset is larger, exhaustive matching might take a long time - consider selecting fewer pairs using image retrieval and hloc/pairs_from_retrieval.py.

In [ ]:
match_features.main(matcher_conf, sfm_pairs, features, outputs, exhaustive=True)

SfM reconstruction

Run COLMAP on the features and matches.

In [ ]:
reconstruction.main(
    sfm_dir,
    images,
    sfm_pairs,
    outputs / feature_file,
    outputs / match_file)

Visualization

We visualize some of the registered images, and color their keypoint by visibility, track length, or triangulated depth.

In [ ]:
visualization.visualize_sfm_2d(sfm_dir / 'models/0', images, color_by='visibility', n=5)
In [ ]:
visualization.visualize_sfm_2d(sfm_dir / 'models/0', images, color_by='track_length', n=5)
In [ ]:
visualization.visualize_sfm_2d(sfm_dir / 'models/0', images, color_by='depth', n=5)