|
from pathlib import Path |
|
import argparse |
|
|
|
from . import colmap_from_nvm |
|
from ... import extract_features, match_features, triangulation |
|
from ... import pairs_from_covisibility, pairs_from_retrieval, localize_sfm |
|
|
|
|
|
CONDITIONS = [ |
|
"dawn", |
|
"dusk", |
|
"night", |
|
"night-rain", |
|
"overcast-summer", |
|
"overcast-winter", |
|
"rain", |
|
"snow", |
|
"sun", |
|
] |
|
|
|
|
|
def generate_query_list(dataset, image_dir, path): |
|
h, w = 1024, 1024 |
|
intrinsics_filename = "intrinsics/{}_intrinsics.txt" |
|
cameras = {} |
|
for side in ["left", "right", "rear"]: |
|
with open(dataset / intrinsics_filename.format(side), "r") as f: |
|
fx = f.readline().split()[1] |
|
fy = f.readline().split()[1] |
|
cx = f.readline().split()[1] |
|
cy = f.readline().split()[1] |
|
assert fx == fy |
|
params = ["SIMPLE_RADIAL", w, h, fx, cx, cy, 0.0] |
|
cameras[side] = [str(p) for p in params] |
|
|
|
queries = sorted(image_dir.glob("**/*.jpg")) |
|
queries = [str(q.relative_to(image_dir.parents[0])) for q in queries] |
|
|
|
out = [[q] + cameras[Path(q).parent.name] for q in queries] |
|
with open(path, "w") as f: |
|
f.write("\n".join(map(" ".join, out))) |
|
|
|
|
|
parser = argparse.ArgumentParser() |
|
parser.add_argument( |
|
"--dataset", |
|
type=Path, |
|
default="datasets/robotcar", |
|
help="Path to the dataset, default: %(default)s", |
|
) |
|
parser.add_argument( |
|
"--outputs", |
|
type=Path, |
|
default="outputs/robotcar", |
|
help="Path to the output directory, default: %(default)s", |
|
) |
|
parser.add_argument( |
|
"--num_covis", |
|
type=int, |
|
default=20, |
|
help="Number of image pairs for SfM, default: %(default)s", |
|
) |
|
parser.add_argument( |
|
"--num_loc", |
|
type=int, |
|
default=20, |
|
help="Number of image pairs for loc, default: %(default)s", |
|
) |
|
args = parser.parse_args() |
|
|
|
|
|
dataset = args.dataset |
|
images = dataset / "images/" |
|
|
|
outputs = args.outputs |
|
outputs.mkdir(exist_ok=True, parents=True) |
|
query_list = outputs / "{condition}_queries_with_intrinsics.txt" |
|
sift_sfm = outputs / "sfm_sift" |
|
reference_sfm = outputs / "sfm_superpoint+superglue" |
|
sfm_pairs = outputs / f"pairs-db-covis{args.num_covis}.txt" |
|
loc_pairs = outputs / f"pairs-query-netvlad{args.num_loc}.txt" |
|
results = outputs / f"RobotCar_hloc_superpoint+superglue_netvlad{args.num_loc}.txt" |
|
|
|
|
|
retrieval_conf = extract_features.confs["netvlad"] |
|
feature_conf = extract_features.confs["superpoint_aachen"] |
|
matcher_conf = match_features.confs["superglue"] |
|
|
|
for condition in CONDITIONS: |
|
generate_query_list( |
|
dataset, images / condition, str(query_list).format(condition=condition) |
|
) |
|
|
|
features = extract_features.main(feature_conf, images, outputs, as_half=True) |
|
|
|
colmap_from_nvm.main( |
|
dataset / "3D-models/all-merged/all.nvm", |
|
dataset / "3D-models/overcast-reference.db", |
|
sift_sfm, |
|
) |
|
pairs_from_covisibility.main(sift_sfm, sfm_pairs, num_matched=args.num_covis) |
|
sfm_matches = match_features.main( |
|
matcher_conf, sfm_pairs, feature_conf["output"], outputs |
|
) |
|
|
|
triangulation.main(reference_sfm, sift_sfm, images, sfm_pairs, features, sfm_matches) |
|
|
|
global_descriptors = extract_features.main(retrieval_conf, images, outputs) |
|
|
|
pairs_from_retrieval.main( |
|
global_descriptors, |
|
loc_pairs, |
|
args.num_loc, |
|
query_prefix=CONDITIONS, |
|
db_model=reference_sfm, |
|
) |
|
loc_matches = match_features.main( |
|
matcher_conf, loc_pairs, feature_conf["output"], outputs |
|
) |
|
|
|
localize_sfm.main( |
|
reference_sfm, |
|
Path(str(query_list).format(condition="*")), |
|
loc_pairs, |
|
features, |
|
loc_matches, |
|
results, |
|
covisibility_clustering=False, |
|
prepend_camera_name=True, |
|
) |
|
|