Realcat commited on
Commit
b7f7f2c
1 Parent(s): 7acaad7

add: xfeat: https://github.com/verlab/accelerated_features

Browse files
common/config.yaml CHANGED
@@ -28,6 +28,10 @@ matcher_zoo:
28
  aspanformer:
29
  matcher: aspanformer
30
  dense: true
 
 
 
 
31
  dedode:
32
  matcher: Dual-Softmax
33
  feature: dedode
 
28
  aspanformer:
29
  matcher: aspanformer
30
  dense: true
31
+ xfeat:
32
+ matcher: NN-mutual
33
+ feature: xfeat
34
+ dense: false
35
  dedode:
36
  matcher: Dual-Softmax
37
  feature: dedode
common/utils.py CHANGED
@@ -18,6 +18,8 @@ from .viz import (
18
  display_matches,
19
  plot_color_line_matches,
20
  )
 
 
21
 
22
  device = "cuda" if torch.cuda.is_available() else "cpu"
23
 
@@ -462,7 +464,7 @@ def run_matching(
462
  # update match config
463
  match_conf["model"]["match_threshold"] = match_threshold
464
  match_conf["model"]["max_keypoints"] = extract_max_keypoints
465
-
466
  matcher = get_model(match_conf)
467
  if model["dense"]:
468
  pred = match_dense.match_images(
@@ -534,9 +536,9 @@ def run_matching(
534
  {"geom_info": geom_info},
535
  choice_estimate_geom,
536
  )
537
-
538
  del pred
539
-
540
  return (
541
  output_keypoints,
542
  output_matches_raw,
 
18
  display_matches,
19
  plot_color_line_matches,
20
  )
21
+ import time
22
+ import matplotlib.pyplot as plt
23
 
24
  device = "cuda" if torch.cuda.is_available() else "cpu"
25
 
 
464
  # update match config
465
  match_conf["model"]["match_threshold"] = match_threshold
466
  match_conf["model"]["max_keypoints"] = extract_max_keypoints
467
+ t1 = time.time()
468
  matcher = get_model(match_conf)
469
  if model["dense"]:
470
  pred = match_dense.match_images(
 
536
  {"geom_info": geom_info},
537
  choice_estimate_geom,
538
  )
539
+ plt.close("all")
540
  del pred
541
+ logger.info(f"TOTAL time: {time.time()-t1:.3f}s")
542
  return (
543
  output_keypoints,
544
  output_matches_raw,
common/viz.py CHANGED
@@ -252,6 +252,7 @@ def draw_matches(
252
  img1: np.ndarray,
253
  conf: np.ndarray,
254
  titles: Optional[List[str]] = None,
 
255
  dpi: int = 150,
256
  path: Optional[str] = None,
257
  pad: float = 0.5,
@@ -370,7 +371,10 @@ def draw_image_pairs(
370
 
371
 
372
  def display_matches(
373
- pred: Dict[str, np.ndarray], titles: List[str] = [], dpi: int = 300
 
 
 
374
  ) -> Tuple[np.ndarray, int]:
375
  """
376
  Displays the matches between two images.
@@ -408,6 +412,7 @@ def display_matches(
408
  mconf,
409
  dpi=dpi,
410
  titles=titles,
 
411
  )
412
  fig = fig_mkpts
413
  if (
 
252
  img1: np.ndarray,
253
  conf: np.ndarray,
254
  titles: Optional[List[str]] = None,
255
+ texts: Optional[List[str]] = None,
256
  dpi: int = 150,
257
  path: Optional[str] = None,
258
  pad: float = 0.5,
 
371
 
372
 
373
  def display_matches(
374
+ pred: Dict[str, np.ndarray],
375
+ titles: List[str] = [],
376
+ texts: List[str] = [],
377
+ dpi: int = 300,
378
  ) -> Tuple[np.ndarray, int]:
379
  """
380
  Displays the matches between two images.
 
412
  mconf,
413
  dpi=dpi,
414
  titles=titles,
415
+ texts=texts,
416
  )
417
  fig = fig_mkpts
418
  if (
hloc/extract_features.py CHANGED
@@ -201,6 +201,17 @@ confs = {
201
  "resize_max": 1600,
202
  },
203
  },
 
 
 
 
 
 
 
 
 
 
 
204
  "alike": {
205
  "output": "feats-alike-n5000-r1600",
206
  "model": {
 
201
  "resize_max": 1600,
202
  },
203
  },
204
+ "xfeat": {
205
+ "output": "feats-xfeat-n5000-r1600",
206
+ "model": {
207
+ "name": "xfeat",
208
+ "max_keypoints": 5000,
209
+ },
210
+ "preprocessing": {
211
+ "grayscale": False,
212
+ "resize_max": 1600,
213
+ },
214
+ },
215
  "alike": {
216
  "output": "feats-alike-n5000-r1600",
217
  "model": {
hloc/extractors/disk.py CHANGED
@@ -1,5 +1,5 @@
1
  import kornia
2
-
3
  from ..utils.base_model import BaseModel
4
 
5
 
@@ -15,6 +15,7 @@ class DISK(BaseModel):
15
 
16
  def _init(self, conf):
17
  self.model = kornia.feature.DISK.from_pretrained(conf["weights"])
 
18
 
19
  def _forward(self, data):
20
  image = data["image"]
 
1
  import kornia
2
+ from hloc import logger
3
  from ..utils.base_model import BaseModel
4
 
5
 
 
15
 
16
  def _init(self, conf):
17
  self.model = kornia.feature.DISK.from_pretrained(conf["weights"])
18
+ logger.info(f"Load DISK model done.")
19
 
20
  def _forward(self, data):
21
  image = data["image"]
hloc/extractors/xfeat.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from pathlib import Path
3
+ from hloc import logger
4
+ from ..utils.base_model import BaseModel
5
+
6
+
7
+ class XFeat(BaseModel):
8
+ default_conf = {
9
+ "keypoint_threshold": 0.005,
10
+ "max_keypoints": -1,
11
+ }
12
+ required_inputs = ["image"]
13
+
14
+ def _init(self, conf):
15
+ self.net = torch.hub.load(
16
+ "verlab/accelerated_features",
17
+ "XFeat",
18
+ pretrained=True,
19
+ top_k=self.conf["max_keypoints"],
20
+ )
21
+ logger.info(f"Load XFeat model done.")
22
+
23
+ def _forward(self, data):
24
+ pred = self.net.detectAndCompute(
25
+ data["image"], top_k=self.conf["max_keypoints"]
26
+ )[0]
27
+ pred = {
28
+ "keypoints": pred["keypoints"][None],
29
+ "scores": pred["scores"][None],
30
+ "descriptors": pred["descriptors"].T[None],
31
+ }
32
+ return pred