Vincentqyw
update: limit keypoints number
60ad158
from pathlib import Path
import argparse
from .utils import create_reference_sfm
from .create_gt_sfm import correct_sfm_with_gt_depth
from ..Cambridge.utils import create_query_list_with_intrinsics, evaluate
from ... import extract_features, match_features, pairs_from_covisibility
from ... import triangulation, localize_sfm, logger
SCENES = ["chess", "fire", "heads", "office", "pumpkin", "redkitchen", "stairs"]
def run_scene(
images,
gt_dir,
retrieval,
outputs,
results,
num_covis,
use_dense_depth,
depth_dir=None,
):
outputs.mkdir(exist_ok=True, parents=True)
ref_sfm_sift = outputs / "sfm_sift"
ref_sfm = outputs / "sfm_superpoint+superglue"
query_list = outputs / "query_list_with_intrinsics.txt"
feature_conf = {
"output": "feats-superpoint-n4096-r1024",
"model": {
"name": "superpoint",
"nms_radius": 3,
"max_keypoints": 4096,
},
"preprocessing": {
"globs": ["*.color.png"],
"grayscale": True,
"resize_max": 1024,
},
}
matcher_conf = match_features.confs["superglue"]
matcher_conf["model"]["sinkhorn_iterations"] = 5
test_list = gt_dir / "list_test.txt"
create_reference_sfm(gt_dir, ref_sfm_sift, test_list)
create_query_list_with_intrinsics(gt_dir, query_list, test_list)
features = extract_features.main(
feature_conf, images, outputs, as_half=True
)
sfm_pairs = outputs / f"pairs-db-covis{num_covis}.txt"
pairs_from_covisibility.main(ref_sfm_sift, sfm_pairs, num_matched=num_covis)
sfm_matches = match_features.main(
matcher_conf, sfm_pairs, feature_conf["output"], outputs
)
if not (use_dense_depth and ref_sfm.exists()):
triangulation.main(
ref_sfm, ref_sfm_sift, images, sfm_pairs, features, sfm_matches
)
if use_dense_depth:
assert depth_dir is not None
ref_sfm_fix = outputs / "sfm_superpoint+superglue+depth"
correct_sfm_with_gt_depth(ref_sfm, depth_dir, ref_sfm_fix)
ref_sfm = ref_sfm_fix
loc_matches = match_features.main(
matcher_conf, retrieval, feature_conf["output"], outputs
)
localize_sfm.main(
ref_sfm,
query_list,
retrieval,
features,
loc_matches,
results,
covisibility_clustering=False,
prepend_camera_name=True,
)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--scenes", default=SCENES, choices=SCENES, nargs="+")
parser.add_argument("--overwrite", action="store_true")
parser.add_argument(
"--dataset",
type=Path,
default="datasets/7scenes",
help="Path to the dataset, default: %(default)s",
)
parser.add_argument(
"--outputs",
type=Path,
default="outputs/7scenes",
help="Path to the output directory, default: %(default)s",
)
parser.add_argument("--use_dense_depth", action="store_true")
parser.add_argument(
"--num_covis",
type=int,
default=30,
help="Number of image pairs for SfM, default: %(default)s",
)
args = parser.parse_args()
gt_dirs = args.dataset / "7scenes_sfm_triangulated/{scene}/triangulated"
retrieval_dirs = args.dataset / "7scenes_densevlad_retrieval_top_10"
all_results = {}
for scene in args.scenes:
logger.info(f'Working on scene "{scene}".')
results = (
args.outputs
/ scene
/ "results_{}.txt".format(
"dense" if args.use_dense_depth else "sparse"
)
)
if args.overwrite or not results.exists():
run_scene(
args.dataset / scene,
Path(str(gt_dirs).format(scene=scene)),
retrieval_dirs / f"{scene}_top10.txt",
args.outputs / scene,
results,
args.num_covis,
args.use_dense_depth,
depth_dir=args.dataset / f"depth/7scenes_{scene}/train/depth",
)
all_results[scene] = results
for scene in args.scenes:
logger.info(f'Evaluate scene "{scene}".')
gt_dir = Path(str(gt_dirs).format(scene=scene))
evaluate(gt_dir, all_results[scene], gt_dir / "list_test.txt")