Spaces:
Running
Running
import argparse | |
from collections import defaultdict | |
from pathlib import Path | |
import numpy as np | |
from tqdm import tqdm | |
from . import logger | |
from .utils.read_write_model import read_model | |
def main(model, output, num_matched): | |
logger.info("Reading the COLMAP model...") | |
cameras, images, points3D = read_model(model) | |
logger.info("Extracting image pairs from covisibility info...") | |
pairs = [] | |
for image_id, image in tqdm(images.items()): | |
matched = image.point3D_ids != -1 | |
points3D_covis = image.point3D_ids[matched] | |
covis = defaultdict(int) | |
for point_id in points3D_covis: | |
for image_covis_id in points3D[point_id].image_ids: | |
if image_covis_id != image_id: | |
covis[image_covis_id] += 1 | |
if len(covis) == 0: | |
logger.info(f"Image {image_id} does not have any covisibility.") | |
continue | |
covis_ids = np.array(list(covis.keys())) | |
covis_num = np.array([covis[i] for i in covis_ids]) | |
if len(covis_ids) <= num_matched: | |
top_covis_ids = covis_ids[np.argsort(-covis_num)] | |
else: | |
# get covisible image ids with top k number of common matches | |
ind_top = np.argpartition(covis_num, -num_matched) | |
ind_top = ind_top[-num_matched:] # unsorted top k | |
ind_top = ind_top[np.argsort(-covis_num[ind_top])] | |
top_covis_ids = [covis_ids[i] for i in ind_top] | |
assert covis_num[ind_top[0]] == np.max(covis_num) | |
for i in top_covis_ids: | |
pair = (image.name, images[i].name) | |
pairs.append(pair) | |
logger.info(f"Found {len(pairs)} pairs.") | |
with open(output, "w") as f: | |
f.write("\n".join(" ".join([i, j]) for i, j in pairs)) | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser() | |
parser.add_argument("--model", required=True, type=Path) | |
parser.add_argument("--output", required=True, type=Path) | |
parser.add_argument("--num_matched", required=True, type=int) | |
args = parser.parse_args() | |
main(**args.__dict__) | |