Skip to content

Commit

Permalink
Dev (#41)
Browse files Browse the repository at this point in the history
* update: ci

* update: download model from HF

* update: ci

* del: sgmnet

* update: submodule sgmnet

* update: ci

* Remove submodule

* update: ci

* update: submodule darkfeat

* update: submodule lanet
  • Loading branch information
Vincentqyw authored Jul 7, 2024
1 parent df195f4 commit 6ad3d61
Show file tree
Hide file tree
Showing 31 changed files with 152 additions and 131 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: CI_CPU

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"

- name: Install dependencies
run: |
pip install -r env-docker.txt
sudo apt-get update && sudo apt-get install ffmpeg libsm6 libxext6 -y
- name: Run tests
run: python test_app_cli.py
12 changes: 6 additions & 6 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@
[submodule "third_party/LightGlue"]
path = third_party/LightGlue
url = https://github.com/cvg/LightGlue.git
[submodule "third_party/SGMNet"]
path = third_party/SGMNet
url = https://github.com/vdvchen/SGMNet.git
[submodule "third_party/DarkFeat"]
path = third_party/DarkFeat
url = https://github.com/THU-LYJ-Lab/DarkFeat.git
[submodule "third_party/DeDoDe"]
path = third_party/DeDoDe
url = https://github.com/Parskatt/DeDoDe.git
Expand Down Expand Up @@ -64,3 +58,9 @@
[submodule "third_party/pram"]
path = third_party/pram
url = https://github.com/feixue94/pram.git
[submodule "third_party/SGMNet"]
path = third_party/SGMNet
url = https://github.com/agipro/SGMNet.git
[submodule "third_party/DarkFeat"]
path = third_party/DarkFeat
url = https://github.com/agipro/DarkFeat.git
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ I provide an example to add local feature in [hloc/extractors/example.py](hloc/e

External contributions are very much welcome. Please follow the [PEP8 style guidelines](https://www.python.org/dev/peps/pep-0008/) using a linter like flake8 (reformat using command `python -m black .`). This is a non-exhaustive list of features that might be valuable additions:

- [x] add [CPU CI](.github/workflows/ci.yml)
- [x] add webcam support
- [x] add [line feature matching](https://github.com/Vincentqyw/LineSegmentsDetection) algorithms
- [x] example to add a new feature extractor / matcher
Expand Down
6 changes: 6 additions & 0 deletions activate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# download submodules
git submodule update --init --recursive

# configuration envs
pip install -r env-docker.txt
sudo apt-get update && sudo apt-get install ffmpeg libsm6 libxext6 -y
7 changes: 7 additions & 0 deletions common/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ matcher_zoo:
DUSt3R:
# TODO: duster is under development
enable: true
skip_ci: true
matcher: duster
dense: true
info:
Expand All @@ -41,6 +42,7 @@ matcher_zoo:
display: true
GIM(dkm):
enable: true
skip_ci: true
matcher: gim(dkm)
dense: true
info:
Expand All @@ -52,6 +54,7 @@ matcher_zoo:
display: true
RoMa:
matcher: roma
skip_ci: true
dense: true
info:
name: RoMa #dispaly name
Expand All @@ -62,6 +65,7 @@ matcher_zoo:
display: true
dkm:
matcher: dkm
skip_ci: true
dense: true
info:
name: DKM #dispaly name
Expand All @@ -82,6 +86,7 @@ matcher_zoo:
display: true
cotr:
enable: false
skip_ci: true
matcher: cotr
dense: true
info:
Expand Down Expand Up @@ -368,6 +373,7 @@ matcher_zoo:
matcher: imp
feature: sfd2
dense: false
skip_ci: true
info:
name: SFD2+IMP #dispaly name
source: "CVPR 2023"
Expand All @@ -380,6 +386,7 @@ matcher_zoo:
matcher: NN-mutual
feature: sfd2
dense: false
skip_ci: true
info:
name: SFD2+MNN #dispaly name
source: "CVPR 2023"
Expand Down
6 changes: 5 additions & 1 deletion env-docker.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@ torchmetrics==0.6.0
torchvision==0.17.1
tqdm==4.65.0
yacs==0.1.8
onnxruntime
onnxruntime
poselib
roma
huggingface_hub
psutil
3 changes: 2 additions & 1 deletion hloc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
from packaging import version
import torch

__version__ = "1.3"

Expand Down Expand Up @@ -30,4 +31,4 @@
minimal_version,
found_version,
)
checkpoints_hub = "https://huggingface.co/spaces/Realcat/image-matching-webui/resolve/main/third_party"
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
3 changes: 2 additions & 1 deletion hloc/extractors/d2net.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from lib.model_test import D2Net as _D2Net
from lib.pyramid import process_multiscale


class D2Net(BaseModel):
default_conf = {
"model_name": "d2_tf.pth",
Expand Down Expand Up @@ -61,4 +62,4 @@ def _forward(self, data):
"keypoints": torch.from_numpy(keypoints)[None],
"scores": torch.from_numpy(scores)[None],
"descriptors": torch.from_numpy(descriptors.T)[None],
}
}
25 changes: 8 additions & 17 deletions hloc/extractors/darkfeat.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import sys
from pathlib import Path
import subprocess
from huggingface_hub import hf_hub_download
from ..utils.base_model import BaseModel
from hloc import logger

Expand All @@ -25,24 +26,14 @@ class DarkFeat(BaseModel):
def _init(self, conf):
model_path = darkfeat_path / "checkpoints" / conf["model_name"]
link = self.weight_urls[conf["model_name"]]
if not model_path.exists():
model_path.parent.mkdir(exist_ok=True)
cmd_wo_proxy = ["gdown", link, "-O", str(model_path)]
cmd = ["gdown", link, "-O", str(model_path), "--proxy", self.proxy]
logger.info(
f"Downloading the DarkFeat model with `{cmd_wo_proxy}`."
)
try:
subprocess.run(cmd_wo_proxy, check=True)
except subprocess.CalledProcessError as e:
logger.info(f"Downloading the DarkFeat model with `{cmd}`.")
try:
subprocess.run(cmd, check=True)
except subprocess.CalledProcessError as e:
logger.error(f"Failed to download the DarkFeat model.")
raise e

self.net = DarkFeat_(model_path)
cached_file = hf_hub_download(
repo_type="space",
repo_id="Realcat/image-matching-webui",
filename="third_party/DarkFeat/checkpoints/DarkFeat.pth",
)

self.net = DarkFeat_(cached_file)
logger.info(f"Load DarkFeat model done.")

def _forward(self, data):
Expand Down
23 changes: 12 additions & 11 deletions hloc/extractors/lanet.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
from pathlib import Path
import torch
import subprocess
from hloc import logger, checkpoints_hub
from huggingface_hub import hf_hub_download
from ..utils.base_model import BaseModel

from hloc import logger
lib_path = Path(__file__).parent / "../../third_party"
sys.path.append(str(lib_path))
from lanet.network_v0.model import PointModel

lanet_path = Path(__file__).parent / "../../third_party/lanet"

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
Expand All @@ -27,16 +28,16 @@ def _init(self, conf):
)
if not model_path.exists():
logger.warning(f"No model found at {model_path}, start downloading")
model_link = "{}/lanet/checkpoints/{}".format(
checkpoints_hub, f'PointModel_{conf["model_name"]}.pth'
)
model_path.parent.mkdir(exist_ok=True)
cmd = [
"wget",
model_link,
"-O",
str(model_path),
]
cached_file = hf_hub_download(
repo_type="space",
repo_id="Realcat/image-matching-webui",
filename="third_party/lanet/checkpoints/PointModel_{}.pth".format(
conf["model_name"]
),
)
cmd = ["cp", str(cached_file), str(model_path.parent)]
logger.info(f"copy model file `{cmd}`.")
subprocess.run(cmd, check=True)

self.net = PointModel(is_test=True)
Expand Down
2 changes: 1 addition & 1 deletion hloc/extractors/r2d2.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sys
from pathlib import Path
import torchvision.transforms as tvf

from hloc import logger
from ..utils.base_model import BaseModel

r2d2_path = Path(__file__).parent / "../../third_party/r2d2"
Expand Down
28 changes: 16 additions & 12 deletions hloc/extractors/rord.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from pathlib import Path
import subprocess
import torch
from huggingface_hub import hf_hub_download

from ..utils.base_model import BaseModel
from hloc import logger
Expand Down Expand Up @@ -29,20 +30,23 @@ class RoRD(BaseModel):
def _init(self, conf):
model_path = conf["checkpoint_dir"] / conf["model_name"]
link = self.weight_urls[conf["model_name"]]

if not model_path.exists():
model_path.parent.mkdir(exist_ok=True)
cmd_wo_proxy = ["gdown", link, "-O", str(model_path)]
cmd = ["gdown", link, "-O", str(model_path), "--proxy", self.proxy]
logger.info(f"Downloading the RoRD model with `{cmd_wo_proxy}`.")
try:
subprocess.run(cmd_wo_proxy, check=True)
except subprocess.CalledProcessError as e:
logger.info(f"Downloading the RoRD model with `{cmd}`.")
try:
subprocess.run(cmd, check=True)
except subprocess.CalledProcessError as e:
logger.error(f"Failed to download the RoRD model.")
raise e
cached_file_0 = hf_hub_download(
repo_type="space",
repo_id="Realcat/image-matching-webui",
filename="third_party/RoRD/models/d2net.pth",
)
cached_file_1 = hf_hub_download(
repo_type="space",
repo_id="Realcat/image-matching-webui",
filename="third_party/RoRD/models/rord.pth",
)

subprocess.run(["cp", cached_file_0, model_path], check=True)
subprocess.run(["cp", cached_file_1, model_path], check=True)

self.net = _RoRD(
model_file=model_path, use_relu=conf["use_relu"], use_cuda=False
)
Expand Down
9 changes: 5 additions & 4 deletions hloc/extractors/sfd2.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@
class SFD2(BaseModel):
default_conf = {
"max_keypoints": 4096,
"model_name": 'sfd2_20230511_210205_resnet4x.79.pth',
"model_name": "sfd2_20230511_210205_resnet4x.79.pth",
"conf_th": 0.001,

}
required_inputs = ["image"]

Expand All @@ -28,13 +27,15 @@ def _init(self, conf):
self.norm_rgb = tvf.Normalize(
mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]
)
model_fn = pram_path / 'weights' / self.conf['model_name']
model_fn = pram_path / "weights" / self.conf["model_name"]
self.net = load_sfd2(weight_path=model_fn).cuda().eval()

logger.info(f"Load SFD2 model done.")

def _forward(self, data):
pred = self.net.extract_local_global(data={'image': self.norm_rgb(data['image'])}, config=self.conf)
pred = self.net.extract_local_global(
data={"image": self.norm_rgb(data["image"])}, config=self.conf
)
out = {
"keypoints": pred["keypoints"][0][None],
"scores": pred["scores"][0][None],
Expand Down
46 changes: 15 additions & 31 deletions hloc/matchers/aspanformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from ..utils import do_system
from pathlib import Path
import subprocess
from huggingface_hub import hf_hub_download

from .. import logger

Expand Down Expand Up @@ -37,37 +38,20 @@ def _init(self, conf):
)
# Download the model.
if not model_path.exists():
# model_path.parent.mkdir(exist_ok=True)
tar_path = aspanformer_path / conf["model_name"]
if not tar_path.exists():
link = self.aspanformer_models[conf["model_name"]]
cmd = [
"gdown",
link,
"-O",
str(tar_path),
"--proxy",
self.proxy,
]
cmd_wo_proxy = ["gdown", link, "-O", str(tar_path)]
logger.info(
f"Downloading the Aspanformer model with `{cmd_wo_proxy}`."
)
try:
subprocess.run(cmd_wo_proxy, check=True)
except subprocess.CalledProcessError as e:
logger.info(
f"Downloading the Aspanformer model with `{cmd}`."
)
try:
subprocess.run(cmd, check=True)
except subprocess.CalledProcessError as e:
logger.error(
f"Failed to download the Aspanformer model."
)
raise e

do_system(f"cd {str(aspanformer_path)} & tar -xvf {str(tar_path)}")
cached_file = hf_hub_download(
repo_type="space",
repo_id="Realcat/image-matching-webui",
filename="third_party/ASpanFormer/weights_aspanformer.tar",
)
cmd = [
"tar",
"-xvf",
str(cached_file),
"-C",
str(aspanformer_path / "weights"),
]
logger.info(f"Unzip model file `{cmd}`.")
subprocess.run(cmd, check=True)

config = get_cfg_defaults()
config.merge_from_file(conf["config_path"])
Expand Down
Loading

0 comments on commit 6ad3d61

Please sign in to comment.