Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dense matching based line matcher #87

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
7490bec
dense matcher based line matching
B1ueber2y Oct 19, 2024
237e215
formatting.
B1ueber2y Oct 19, 2024
009b0db
add a test script.
B1ueber2y Oct 19, 2024
b95f8c5
minor.
B1ueber2y Oct 19, 2024
15e88b3
formatting.
B1ueber2y Oct 19, 2024
62ed189
Merge branch 'main' into features/dense_matching
B1ueber2y Oct 19, 2024
4acbf88
fix formatting with ruff.
B1ueber2y Oct 19, 2024
786211c
add tiny roma.
B1ueber2y Oct 21, 2024
be25734
Merge branch 'main' into features/dense_matching
B1ueber2y Oct 21, 2024
7248ddd
minor.
B1ueber2y Oct 21, 2024
1207f5f
Fix different input/output conventions for tiny RoMa
Oct 23, 2024
71b9a07
formattin.
B1ueber2y Oct 24, 2024
9df66fc
refactor. set overlap threshold to 0.2
B1ueber2y Oct 24, 2024
9d43541
Merge branch 'main' into features/dense_matching
B1ueber2y Oct 24, 2024
8f2b91a
Minor simplifications
rpautrat Oct 26, 2024
b98ade9
RoMa mode in config
rpautrat Oct 28, 2024
2e967af
One-to-many matching
rpautrat Oct 28, 2024
f20ed21
Mutual nearest neighbors + small fixes
rpautrat Nov 5, 2024
d355819
Merge branch 'main' into features/dense_matching
B1ueber2y Nov 24, 2024
9141712
merge and fix linting issues.
B1ueber2y Nov 24, 2024
c8bb7d8
Merge branch 'main' into features/dense_matching
B1ueber2y Nov 28, 2024
bb5b73a
Merge branch 'main' into features/dense_matching
B1ueber2y Nov 29, 2024
ae78791
Merge branch 'main' into features/dense_matching
B1ueber2y Dec 13, 2024
9402743
Make Gluestick install editable
Dec 15, 2024
b7a7b0f
Update the dense matcher configuration
Dec 15, 2024
8b5af66
Format
rpautrat Dec 15, 2024
48782c1
Merge branch 'main' into features/dense_matching
B1ueber2y Dec 15, 2024
12c9684
Revert editable GlueStick
rpautrat Dec 16, 2024
bf729ed
Merge branch 'features/dense_matching' of github.com:cvg/limap into f…
rpautrat Dec 16, 2024
adc1047
Merge branch 'main' into features/dense_matching
B1ueber2y Jan 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cfgs/localization/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ line2d:
skip_exists: False
superglue:
weights: "outdoor" # ["indoor", "outdoor"] for selecting superglue models
dense:
one_to_many: False
weights: "outdoor" # ["indoor", "outdoor", "tiny_outdoor"] for selecting RoMa models
var2d: # in pixels
sold2: 5.0
lsd: 2.0
Expand Down
3 changes: 3 additions & 0 deletions cfgs/triangulation/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ line2d:
skip_exists: False
superglue:
weights: "outdoor" # ["indoor", "outdoor"] for selecting superglue models
dense:
one_to_many: False
weights: "outdoor" # ["indoor", "outdoor", "tiny_outdoor"] for selecting RoMa models
var2d: # in pixels
sold2: 5.0
lsd: 2.0
Expand Down
8 changes: 8 additions & 0 deletions limap/line2d/dense/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from .extractor import DenseNaiveExtractor
from .matcher import BaseDenseLineMatcherOptions, RoMaLineMatcher

__all__ = [
"BaseDenseLineMatcherOptions",
"DenseNaiveExtractor",
"RoMaLineMatcher",
]
4 changes: 4 additions & 0 deletions limap/line2d/dense/dense_matcher/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .base import BaseDenseMatcher
from .roma import RoMa

__all__ = ["BaseDenseMatcher", "RoMa"]
34 changes: 34 additions & 0 deletions limap/line2d/dense/dense_matcher/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import torch


class BaseDenseMatcher:
def __init__(self):
pass

def to_normalized_coordinates(self, coords, h, w):
"""
coords: (..., 2) in the order x, y
"""
coords_x = 2 / w * coords[..., 0] - 1
coords_y = 2 / h * coords[..., 1] - 1
return torch.stack([coords_x, coords_y], axis=-1)

def to_unnormalized_coordinates(self, coords, h, w):
"""
Inverse operation of `to_normalized_coordinates`
"""
coords_x = (coords[..., 0] + 1) * w / 2
coords_y = (coords[..., 1] + 1) * h / 2
return torch.stack([coords_x, coords_y], axis=-1)

def get_sample_thresh(self):
"""
return sample threshold
"""
raise NotImplementedError

def get_warping_symmetric(self, img1, img2):
"""
return warp_1to2 ([-1, 1]), cert_1to2, warp_2to1([-1, 1]), cert_2to1
"""
raise NotImplementedError
48 changes: 48 additions & 0 deletions limap/line2d/dense/dense_matcher/roma.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import romatch
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

romatch is not included in requirements.txt or dependencies

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we making a separate installation, as we now already make HAWP, LBD separately installed to reduce dependencies.

from PIL import Image

from .base import BaseDenseMatcher


class RoMa(BaseDenseMatcher):
def __init__(self, mode="outdoor", device="cuda"):
super(RoMa).__init__()
self.output_res = 864
self.mode = mode
if mode == "outdoor":
self.model = romatch.roma_outdoor(
device=device, coarse_res=560, upsample_res=self.output_res
)
elif mode == "indoor":
self.model = romatch.roma_indoor(
device=device, coarse_res=560, upsample_res=self.output_res
)
elif mode == "tiny_outdoor":
self.model = romatch.tiny_roma_v1_outdoor(device=device)
else:
raise ValueError(f"Unknown mode for RoMa: {mode}")

def get_sample_thresh(self):
return self.model.sample_thresh

def get_warping_symmetric(self, img1, img2):
pil_img1 = Image.fromarray(img1)
pil_img2 = Image.fromarray(img2)
warp, certainty = self.model.match(pil_img1, pil_img2, batched=False)
if self.mode.startswith("tiny"):
warp2_to_1, certainty2_to_1 = self.model.match(
pil_img2, pil_img1, batched=False
)
return (
warp[:, :, 2:],
certainty,
warp2_to_1[:, :, 2:],
certainty2_to_1,
)
else:
return (
warp[:, : self.output_res, 2:],
certainty[:, : self.output_res],
warp[:, self.output_res :, :2],
certainty[:, self.output_res :],
)
43 changes: 43 additions & 0 deletions limap/line2d/dense/extractor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import os

import numpy as np

import limap.util.io as limapio

from ..base_detector import BaseDetector, DefaultDetectorOptions


class DenseNaiveExtractor(BaseDetector):
def __init__(self, options=DefaultDetectorOptions, device=None):
super().__init__(options)

def get_module_name(self):
return "dense_naive"

def get_descinfo_fname(self, descinfo_folder, img_id):
fname = os.path.join(descinfo_folder, f"descinfo_{img_id}.npz")
return fname

def save_descinfo(self, descinfo_folder, img_id, descinfo):
limapio.check_makedirs(descinfo_folder)
fname = self.get_descinfo_fname(descinfo_folder, img_id)
limapio.save_npz(fname, descinfo)

def read_descinfo(self, descinfo_folder, img_id):
fname = self.get_descinfo_fname(descinfo_folder, img_id)
descinfo = limapio.read_npz(fname)
return descinfo

def extract(self, camview, segs):
img = camview.read_image()
lines = segs[:, :4].reshape(-1, 2, 2)
scores = segs[:, -1] * np.sqrt(
np.linalg.norm(segs[:, :2] - segs[:, 2:4], axis=1)
)
descinfo = {
"image": img,
"image_shape": img.shape,
"lines": lines,
"scores": scores,
}
return descinfo
Loading
Loading