image-matching-webui / hloc /pairs_from_covisibility.py
Vincentqyw
update: sync with hloc
4c88343
raw
history blame
2.09 kB
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__)