Spaces:
Runtime error
Runtime error
Vincentqyw
commited on
Commit
·
49a0323
1
Parent(s):
733c569
update: rord
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitignore +4 -0
- app.py +6 -3
- common/utils.py +10 -1
- hloc/extract_features.py +12 -0
- hloc/extractors/alike.py +0 -1
- hloc/extractors/d2net.py +0 -1
- hloc/extractors/darkfeat.py +1 -4
- hloc/extractors/dedode.py +1 -3
- hloc/extractors/example.py +1 -3
- hloc/extractors/fire_local.py +1 -2
- hloc/extractors/netvlad.py +1 -3
- hloc/extractors/rord.py +75 -0
- hloc/matchers/aspanformer.py +4 -3
- hloc/matchers/dkm.py +1 -3
- hloc/matchers/gluestick.py +1 -3
- hloc/matchers/lightglue.py +1 -2
- hloc/matchers/roma.py +1 -3
- hloc/matchers/sgmnet.py +1 -2
- hloc/matchers/sold2.py +14 -7
- hloc/utils/__init__.py +2 -2
- third_party/RoRD/LICENSE +251 -0
- third_party/RoRD/assets/register_ortho.jpg +3 -0
- third_party/RoRD/assets/register_persp.jpg +3 -0
- third_party/RoRD/assets/register_pointcloud.jpg +3 -0
- third_party/RoRD/assets/rord_evalRT.jpg +3 -0
- third_party/RoRD/assets/rord_extract.jpg +3 -0
- third_party/RoRD/assets/sift_extract.jpg +3 -0
- third_party/RoRD/assets/teaser2.jpg +3 -0
- third_party/RoRD/configs/camera.txt +3 -0
- third_party/RoRD/configs/train_scenes.txt +7 -0
- third_party/RoRD/configs/train_scenes_small.txt +1 -0
- third_party/RoRD/demo/__init__.py +0 -0
- third_party/RoRD/demo/depth/depth1_1.png +3 -0
- third_party/RoRD/demo/depth/depth1_2.png +3 -0
- third_party/RoRD/demo/depth/depth2_1.png +3 -0
- third_party/RoRD/demo/depth/depth2_2.png +3 -0
- third_party/RoRD/demo/depth/depth3_1.png +3 -0
- third_party/RoRD/demo/depth/depth3_2.png +3 -0
- third_party/RoRD/demo/register.py +265 -0
- third_party/RoRD/demo/rgb/rgb1_1.jpg +3 -0
- third_party/RoRD/demo/rgb/rgb1_1.npy +3 -0
- third_party/RoRD/demo/rgb/rgb1_2.jpg +3 -0
- third_party/RoRD/demo/rgb/rgb1_2.npy +3 -0
- third_party/RoRD/demo/rgb/rgb2_1.jpg +3 -0
- third_party/RoRD/demo/rgb/rgb2_1.npy +3 -0
- third_party/RoRD/demo/rgb/rgb2_2.jpg +3 -0
- third_party/RoRD/demo/rgb/rgb2_2.npy +3 -0
- third_party/RoRD/demo/rgb/rgb3_1.jpg +3 -0
- third_party/RoRD/demo/rgb/rgb3_1.npy +3 -0
- third_party/RoRD/demo/rgb/rgb3_2.jpg +3 -0
.gitignore
CHANGED
|
@@ -17,3 +17,7 @@ third_party/REKD
|
|
| 17 |
Dockerfile
|
| 18 |
hloc/matchers/dedode.py
|
| 19 |
gradio_cached_examples
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
Dockerfile
|
| 18 |
hloc/matchers/dedode.py
|
| 19 |
gradio_cached_examples
|
| 20 |
+
|
| 21 |
+
hloc/matchers/quadtree.py
|
| 22 |
+
third_party/QuadTreeAttention
|
| 23 |
+
desktop.ini
|
app.py
CHANGED
|
@@ -14,6 +14,9 @@ This Space demonstrates [Image Matching WebUI](https://github.com/Vincentqyw/ima
|
|
| 14 |
|
| 15 |
🔎 For more details about supported local features and matchers, please refer to https://github.com/Vincentqyw/image-matching-webui
|
| 16 |
|
|
|
|
|
|
|
|
|
|
| 17 |
"""
|
| 18 |
|
| 19 |
|
|
@@ -102,9 +105,9 @@ def run(config):
|
|
| 102 |
)
|
| 103 |
|
| 104 |
with gr.Row():
|
| 105 |
-
button_reset = gr.Button(
|
| 106 |
button_run = gr.Button(
|
| 107 |
-
|
| 108 |
)
|
| 109 |
|
| 110 |
with gr.Accordion("Advanced Setting", open=False):
|
|
@@ -242,7 +245,7 @@ def run(config):
|
|
| 242 |
)
|
| 243 |
with gr.Accordion("Open for More: Geometry info", open=False):
|
| 244 |
geometry_result = gr.JSON(label="Reconstructed Geometry")
|
| 245 |
-
|
| 246 |
# callbacks
|
| 247 |
match_image_src.change(
|
| 248 |
fn=ui_change_imagebox,
|
|
|
|
| 14 |
|
| 15 |
🔎 For more details about supported local features and matchers, please refer to https://github.com/Vincentqyw/image-matching-webui
|
| 16 |
|
| 17 |
+
🚀 All algorithms run on CPU for inference on HF, causing slow speeds and high latency. For faster inference, please download the [source code](https://github.com/Vincentqyw/image-matching-webui) for local deployment or check [openxlab space](https://github.com/Vincentqyw/image-matching-webui) and [direct URL](https://g-app-center-083997-7409-n9elr1.openxlab.space)
|
| 18 |
+
|
| 19 |
+
🐛 Your feedback is valuable to me. Please do not hesitate to report any bugs [here](https://github.com/Vincentqyw/image-matching-webui/issues).
|
| 20 |
"""
|
| 21 |
|
| 22 |
|
|
|
|
| 105 |
)
|
| 106 |
|
| 107 |
with gr.Row():
|
| 108 |
+
button_reset = gr.Button(value="Reset")
|
| 109 |
button_run = gr.Button(
|
| 110 |
+
value="Run Match", variant="primary"
|
| 111 |
)
|
| 112 |
|
| 113 |
with gr.Accordion("Advanced Setting", open=False):
|
|
|
|
| 245 |
)
|
| 246 |
with gr.Accordion("Open for More: Geometry info", open=False):
|
| 247 |
geometry_result = gr.JSON(label="Reconstructed Geometry")
|
| 248 |
+
|
| 249 |
# callbacks
|
| 250 |
match_image_src.change(
|
| 251 |
fn=ui_change_imagebox,
|
common/utils.py
CHANGED
|
@@ -48,6 +48,7 @@ def gen_examples():
|
|
| 48 |
pairs = list(combinations(imgs_list, 2))
|
| 49 |
selected = random.sample(range(len(pairs)), count)
|
| 50 |
return [pairs[i] for i in selected]
|
|
|
|
| 51 |
# image pair path
|
| 52 |
path = "datasets/sacre_coeur/mapping"
|
| 53 |
pairs = gen_images_pairs(path, len(example_matchers))
|
|
@@ -176,7 +177,10 @@ def compute_geom(
|
|
| 176 |
if H is not None:
|
| 177 |
geo_info["Homography"] = H.tolist()
|
| 178 |
_, H1, H2 = cv2.stereoRectifyUncalibrated(
|
| 179 |
-
mkpts0.reshape(-1, 2),
|
|
|
|
|
|
|
|
|
|
| 180 |
)
|
| 181 |
geo_info["H1"] = H1.tolist()
|
| 182 |
geo_info["H2"] = H2.tolist()
|
|
@@ -504,6 +508,11 @@ matcher_zoo = {
|
|
| 504 |
"config_feature": extract_features.confs["d2net-ss"],
|
| 505 |
"dense": False,
|
| 506 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 507 |
# "d2net-ms": {
|
| 508 |
# "config": match_features.confs["NN-mutual"],
|
| 509 |
# "config_feature": extract_features.confs["d2net-ms"],
|
|
|
|
| 48 |
pairs = list(combinations(imgs_list, 2))
|
| 49 |
selected = random.sample(range(len(pairs)), count)
|
| 50 |
return [pairs[i] for i in selected]
|
| 51 |
+
|
| 52 |
# image pair path
|
| 53 |
path = "datasets/sacre_coeur/mapping"
|
| 54 |
pairs = gen_images_pairs(path, len(example_matchers))
|
|
|
|
| 177 |
if H is not None:
|
| 178 |
geo_info["Homography"] = H.tolist()
|
| 179 |
_, H1, H2 = cv2.stereoRectifyUncalibrated(
|
| 180 |
+
mkpts0.reshape(-1, 2),
|
| 181 |
+
mkpts1.reshape(-1, 2),
|
| 182 |
+
F,
|
| 183 |
+
imgSize=(w1, h1),
|
| 184 |
)
|
| 185 |
geo_info["H1"] = H1.tolist()
|
| 186 |
geo_info["H2"] = H2.tolist()
|
|
|
|
| 508 |
"config_feature": extract_features.confs["d2net-ss"],
|
| 509 |
"dense": False,
|
| 510 |
},
|
| 511 |
+
"rord": {
|
| 512 |
+
"config": match_features.confs["NN-mutual"],
|
| 513 |
+
"config_feature": extract_features.confs["rord"],
|
| 514 |
+
"dense": False,
|
| 515 |
+
},
|
| 516 |
# "d2net-ms": {
|
| 517 |
# "config": match_features.confs["NN-mutual"],
|
| 518 |
# "config_feature": extract_features.confs["d2net-ms"],
|
hloc/extract_features.py
CHANGED
|
@@ -115,6 +115,18 @@ confs = {
|
|
| 115 |
"resize_max": 1600,
|
| 116 |
},
|
| 117 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
"rootsift": {
|
| 119 |
"output": "feats-rootsift-n5000-r1600",
|
| 120 |
"model": {
|
|
|
|
| 115 |
"resize_max": 1600,
|
| 116 |
},
|
| 117 |
},
|
| 118 |
+
"rord": {
|
| 119 |
+
"output": "feats-rord-ss-n5000-r1600",
|
| 120 |
+
"model": {
|
| 121 |
+
"name": "rord",
|
| 122 |
+
"multiscale": False,
|
| 123 |
+
"max_keypoints": 5000,
|
| 124 |
+
},
|
| 125 |
+
"preprocessing": {
|
| 126 |
+
"grayscale": False,
|
| 127 |
+
"resize_max": 1600,
|
| 128 |
+
},
|
| 129 |
+
},
|
| 130 |
"rootsift": {
|
| 131 |
"output": "feats-rootsift-n5000-r1600",
|
| 132 |
"model": {
|
hloc/extractors/alike.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
-
import subprocess
|
| 4 |
import torch
|
| 5 |
|
| 6 |
from ..utils.base_model import BaseModel
|
|
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
|
|
|
| 3 |
import torch
|
| 4 |
|
| 5 |
from ..utils.base_model import BaseModel
|
hloc/extractors/d2net.py
CHANGED
|
@@ -10,7 +10,6 @@ sys.path.append(str(d2net_path))
|
|
| 10 |
from lib.model_test import D2Net as _D2Net
|
| 11 |
from lib.pyramid import process_multiscale
|
| 12 |
|
| 13 |
-
|
| 14 |
class D2Net(BaseModel):
|
| 15 |
default_conf = {
|
| 16 |
"model_name": "d2_tf.pth",
|
|
|
|
| 10 |
from lib.model_test import D2Net as _D2Net
|
| 11 |
from lib.pyramid import process_multiscale
|
| 12 |
|
|
|
|
| 13 |
class D2Net(BaseModel):
|
| 14 |
default_conf = {
|
| 15 |
"model_name": "d2_tf.pth",
|
hloc/extractors/darkfeat.py
CHANGED
|
@@ -1,11 +1,8 @@
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
import subprocess
|
| 4 |
-
import logging
|
| 5 |
-
|
| 6 |
from ..utils.base_model import BaseModel
|
| 7 |
-
|
| 8 |
-
logger = logging.getLogger(__name__)
|
| 9 |
|
| 10 |
darkfeat_path = Path(__file__).parent / "../../third_party/DarkFeat"
|
| 11 |
sys.path.append(str(darkfeat_path))
|
|
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
import subprocess
|
|
|
|
|
|
|
| 4 |
from ..utils.base_model import BaseModel
|
| 5 |
+
from .. import logger
|
|
|
|
| 6 |
|
| 7 |
darkfeat_path = Path(__file__).parent / "../../third_party/DarkFeat"
|
| 8 |
sys.path.append(str(darkfeat_path))
|
hloc/extractors/dedode.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
import subprocess
|
| 4 |
-
import logging
|
| 5 |
import torch
|
| 6 |
from PIL import Image
|
| 7 |
from ..utils.base_model import BaseModel
|
|
|
|
| 8 |
import torchvision.transforms as transforms
|
| 9 |
|
| 10 |
dedode_path = Path(__file__).parent / "../../third_party/DeDoDe"
|
|
@@ -14,8 +14,6 @@ from DeDoDe import dedode_detector_L, dedode_descriptor_B
|
|
| 14 |
from DeDoDe.utils import to_pixel_coords
|
| 15 |
|
| 16 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 17 |
-
logger = logging.getLogger(__name__)
|
| 18 |
-
|
| 19 |
|
| 20 |
class DeDoDe(BaseModel):
|
| 21 |
default_conf = {
|
|
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
import subprocess
|
|
|
|
| 4 |
import torch
|
| 5 |
from PIL import Image
|
| 6 |
from ..utils.base_model import BaseModel
|
| 7 |
+
from .. import logger
|
| 8 |
import torchvision.transforms as transforms
|
| 9 |
|
| 10 |
dedode_path = Path(__file__).parent / "../../third_party/DeDoDe"
|
|
|
|
| 14 |
from DeDoDe.utils import to_pixel_coords
|
| 15 |
|
| 16 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
|
|
|
|
|
| 17 |
|
| 18 |
class DeDoDe(BaseModel):
|
| 19 |
default_conf = {
|
hloc/extractors/example.py
CHANGED
|
@@ -2,7 +2,7 @@ import sys
|
|
| 2 |
from pathlib import Path
|
| 3 |
import subprocess
|
| 4 |
import torch
|
| 5 |
-
import
|
| 6 |
|
| 7 |
from ..utils.base_model import BaseModel
|
| 8 |
|
|
@@ -12,8 +12,6 @@ sys.path.append(str(example_path))
|
|
| 12 |
# import some modules here
|
| 13 |
|
| 14 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 15 |
-
logger = logging.getLogger(__name__)
|
| 16 |
-
|
| 17 |
|
| 18 |
class Example(BaseModel):
|
| 19 |
# change to your default configs
|
|
|
|
| 2 |
from pathlib import Path
|
| 3 |
import subprocess
|
| 4 |
import torch
|
| 5 |
+
from .. import logger
|
| 6 |
|
| 7 |
from ..utils.base_model import BaseModel
|
| 8 |
|
|
|
|
| 12 |
# import some modules here
|
| 13 |
|
| 14 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
|
|
|
|
|
| 15 |
|
| 16 |
class Example(BaseModel):
|
| 17 |
# change to your default configs
|
hloc/extractors/fire_local.py
CHANGED
|
@@ -1,13 +1,12 @@
|
|
| 1 |
from pathlib import Path
|
| 2 |
import subprocess
|
| 3 |
-
import logging
|
| 4 |
import sys
|
| 5 |
import torch
|
| 6 |
import torchvision.transforms as tvf
|
| 7 |
|
| 8 |
from ..utils.base_model import BaseModel
|
|
|
|
| 9 |
|
| 10 |
-
logger = logging.getLogger(__name__)
|
| 11 |
fire_path = Path(__file__).parent / "../../third_party/fire"
|
| 12 |
|
| 13 |
sys.path.append(str(fire_path))
|
|
|
|
| 1 |
from pathlib import Path
|
| 2 |
import subprocess
|
|
|
|
| 3 |
import sys
|
| 4 |
import torch
|
| 5 |
import torchvision.transforms as tvf
|
| 6 |
|
| 7 |
from ..utils.base_model import BaseModel
|
| 8 |
+
from .. import logger
|
| 9 |
|
|
|
|
| 10 |
fire_path = Path(__file__).parent / "../../third_party/fire"
|
| 11 |
|
| 12 |
sys.path.append(str(fire_path))
|
hloc/extractors/netvlad.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
| 1 |
from pathlib import Path
|
| 2 |
import subprocess
|
| 3 |
-
import logging
|
| 4 |
import numpy as np
|
| 5 |
import torch
|
| 6 |
import torch.nn as nn
|
|
@@ -9,8 +8,7 @@ import torchvision.models as models
|
|
| 9 |
from scipy.io import loadmat
|
| 10 |
|
| 11 |
from ..utils.base_model import BaseModel
|
| 12 |
-
|
| 13 |
-
logger = logging.getLogger(__name__)
|
| 14 |
|
| 15 |
EPS = 1e-6
|
| 16 |
|
|
|
|
| 1 |
from pathlib import Path
|
| 2 |
import subprocess
|
|
|
|
| 3 |
import numpy as np
|
| 4 |
import torch
|
| 5 |
import torch.nn as nn
|
|
|
|
| 8 |
from scipy.io import loadmat
|
| 9 |
|
| 10 |
from ..utils.base_model import BaseModel
|
| 11 |
+
from .. import logger
|
|
|
|
| 12 |
|
| 13 |
EPS = 1e-6
|
| 14 |
|
hloc/extractors/rord.py
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
import subprocess
|
| 4 |
+
import torch
|
| 5 |
+
|
| 6 |
+
from ..utils.base_model import BaseModel
|
| 7 |
+
from .. import logger
|
| 8 |
+
|
| 9 |
+
rord_path = Path(__file__).parent / "../../third_party/RoRD"
|
| 10 |
+
sys.path.append(str(rord_path))
|
| 11 |
+
from lib.model_test import D2Net as _RoRD
|
| 12 |
+
from lib.pyramid import process_multiscale
|
| 13 |
+
|
| 14 |
+
class RoRD(BaseModel):
|
| 15 |
+
default_conf = {
|
| 16 |
+
"model_name": "rord.pth",
|
| 17 |
+
"checkpoint_dir": rord_path / "models",
|
| 18 |
+
"use_relu": True,
|
| 19 |
+
"multiscale": False,
|
| 20 |
+
"max_keypoints": 1024,
|
| 21 |
+
}
|
| 22 |
+
required_inputs = ["image"]
|
| 23 |
+
weight_urls = {
|
| 24 |
+
"rord.pth": "https://drive.google.com/uc?id=12414ZGKwgPAjNTGtNrlB4VV9l7W76B2o&confirm=t",
|
| 25 |
+
}
|
| 26 |
+
proxy = "http://localhost:1080"
|
| 27 |
+
|
| 28 |
+
def _init(self, conf):
|
| 29 |
+
model_path = conf["checkpoint_dir"] / conf["model_name"]
|
| 30 |
+
link = self.weight_urls[conf["model_name"]]
|
| 31 |
+
if not model_path.exists():
|
| 32 |
+
model_path.parent.mkdir(exist_ok=True)
|
| 33 |
+
cmd_wo_proxy = ["gdown", link, "-O", str(model_path)]
|
| 34 |
+
cmd = ["gdown", link, "-O", str(model_path), "--proxy", self.proxy]
|
| 35 |
+
logger.info(
|
| 36 |
+
f"Downloading the RoRD model with `{cmd_wo_proxy}`."
|
| 37 |
+
)
|
| 38 |
+
try:
|
| 39 |
+
subprocess.run(cmd_wo_proxy, check=True)
|
| 40 |
+
except subprocess.CalledProcessError as e:
|
| 41 |
+
logger.info(f"Downloading the RoRD model with `{cmd}`.")
|
| 42 |
+
try:
|
| 43 |
+
subprocess.run(cmd, check=True)
|
| 44 |
+
except subprocess.CalledProcessError as e:
|
| 45 |
+
logger.error(f"Failed to download the RoRD model.")
|
| 46 |
+
raise e
|
| 47 |
+
logger.info("RoRD model loaded.")
|
| 48 |
+
self.net = _RoRD(
|
| 49 |
+
model_file=model_path, use_relu=conf["use_relu"], use_cuda=False
|
| 50 |
+
)
|
| 51 |
+
|
| 52 |
+
def _forward(self, data):
|
| 53 |
+
image = data["image"]
|
| 54 |
+
image = image.flip(1) # RGB -> BGR
|
| 55 |
+
norm = image.new_tensor([103.939, 116.779, 123.68])
|
| 56 |
+
image = image * 255 - norm.view(1, 3, 1, 1) # caffe normalization
|
| 57 |
+
|
| 58 |
+
if self.conf["multiscale"]:
|
| 59 |
+
keypoints, scores, descriptors = process_multiscale(image, self.net)
|
| 60 |
+
else:
|
| 61 |
+
keypoints, scores, descriptors = process_multiscale(
|
| 62 |
+
image, self.net, scales=[1]
|
| 63 |
+
)
|
| 64 |
+
keypoints = keypoints[:, [1, 0]] # (x, y) and remove the scale
|
| 65 |
+
|
| 66 |
+
idxs = scores.argsort()[-self.conf["max_keypoints"] or None :]
|
| 67 |
+
keypoints = keypoints[idxs, :2]
|
| 68 |
+
descriptors = descriptors[idxs]
|
| 69 |
+
scores = scores[idxs]
|
| 70 |
+
|
| 71 |
+
return {
|
| 72 |
+
"keypoints": torch.from_numpy(keypoints)[None],
|
| 73 |
+
"scores": torch.from_numpy(scores)[None],
|
| 74 |
+
"descriptors": torch.from_numpy(descriptors.T)[None],
|
| 75 |
+
}
|
hloc/matchers/aspanformer.py
CHANGED
|
@@ -4,9 +4,8 @@ from ..utils.base_model import BaseModel
|
|
| 4 |
from ..utils import do_system
|
| 5 |
from pathlib import Path
|
| 6 |
import subprocess
|
| 7 |
-
import logging
|
| 8 |
|
| 9 |
-
|
| 10 |
|
| 11 |
sys.path.append(str(Path(__file__).parent / "../../third_party"))
|
| 12 |
from ASpanFormer.src.ASpanFormer.aspanformer import ASpanFormer as _ASpanFormer
|
|
@@ -77,7 +76,9 @@ class ASpanFormer(BaseModel):
|
|
| 77 |
|
| 78 |
# update: match threshold
|
| 79 |
_config["aspan"]["match_coarse"]["thr"] = conf["match_threshold"]
|
| 80 |
-
_config["aspan"]["match_coarse"]["skh_iters"] = conf[
|
|
|
|
|
|
|
| 81 |
|
| 82 |
self.net = _ASpanFormer(config=_config["aspan"])
|
| 83 |
weight_path = model_path
|
|
|
|
| 4 |
from ..utils import do_system
|
| 5 |
from pathlib import Path
|
| 6 |
import subprocess
|
|
|
|
| 7 |
|
| 8 |
+
from .. import logger
|
| 9 |
|
| 10 |
sys.path.append(str(Path(__file__).parent / "../../third_party"))
|
| 11 |
from ASpanFormer.src.ASpanFormer.aspanformer import ASpanFormer as _ASpanFormer
|
|
|
|
| 76 |
|
| 77 |
# update: match threshold
|
| 78 |
_config["aspan"]["match_coarse"]["thr"] = conf["match_threshold"]
|
| 79 |
+
_config["aspan"]["match_coarse"]["skh_iters"] = conf[
|
| 80 |
+
"sinkhorn_iterations"
|
| 81 |
+
]
|
| 82 |
|
| 83 |
self.net = _ASpanFormer(config=_config["aspan"])
|
| 84 |
weight_path = model_path
|
hloc/matchers/dkm.py
CHANGED
|
@@ -3,16 +3,14 @@ from pathlib import Path
|
|
| 3 |
import torch
|
| 4 |
from PIL import Image
|
| 5 |
import subprocess
|
| 6 |
-
import logging
|
| 7 |
from ..utils.base_model import BaseModel
|
|
|
|
| 8 |
|
| 9 |
sys.path.append(str(Path(__file__).parent / "../../third_party"))
|
| 10 |
from DKM.dkm import DKMv3_outdoor
|
| 11 |
|
| 12 |
dkm_path = Path(__file__).parent / "../../third_party/DKM"
|
| 13 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 14 |
-
logger = logging.getLogger(__name__)
|
| 15 |
-
|
| 16 |
|
| 17 |
class DKMv3(BaseModel):
|
| 18 |
default_conf = {
|
|
|
|
| 3 |
import torch
|
| 4 |
from PIL import Image
|
| 5 |
import subprocess
|
|
|
|
| 6 |
from ..utils.base_model import BaseModel
|
| 7 |
+
from .. import logger
|
| 8 |
|
| 9 |
sys.path.append(str(Path(__file__).parent / "../../third_party"))
|
| 10 |
from DKM.dkm import DKMv3_outdoor
|
| 11 |
|
| 12 |
dkm_path = Path(__file__).parent / "../../third_party/DKM"
|
| 13 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
|
|
|
|
|
| 14 |
|
| 15 |
class DKMv3(BaseModel):
|
| 16 |
default_conf = {
|
hloc/matchers/gluestick.py
CHANGED
|
@@ -1,11 +1,9 @@
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
import subprocess
|
| 4 |
-
import logging
|
| 5 |
import torch
|
| 6 |
from ..utils.base_model import BaseModel
|
| 7 |
-
|
| 8 |
-
logger = logging.getLogger(__name__)
|
| 9 |
|
| 10 |
gluestick_path = Path(__file__).parent / "../../third_party/GlueStick"
|
| 11 |
sys.path.append(str(gluestick_path))
|
|
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
import subprocess
|
|
|
|
| 4 |
import torch
|
| 5 |
from ..utils.base_model import BaseModel
|
| 6 |
+
from .. import logger
|
|
|
|
| 7 |
|
| 8 |
gluestick_path = Path(__file__).parent / "../../third_party/GlueStick"
|
| 9 |
sys.path.append(str(gluestick_path))
|
hloc/matchers/lightglue.py
CHANGED
|
@@ -1,9 +1,8 @@
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
-
import logging
|
| 4 |
from ..utils.base_model import BaseModel
|
|
|
|
| 5 |
|
| 6 |
-
logger = logging.getLogger(__name__)
|
| 7 |
lightglue_path = Path(__file__).parent / "../../third_party/LightGlue"
|
| 8 |
sys.path.append(str(lightglue_path))
|
| 9 |
from lightglue import LightGlue as LG
|
|
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
|
|
|
| 3 |
from ..utils.base_model import BaseModel
|
| 4 |
+
from .. import logger
|
| 5 |
|
|
|
|
| 6 |
lightglue_path = Path(__file__).parent / "../../third_party/LightGlue"
|
| 7 |
sys.path.append(str(lightglue_path))
|
| 8 |
from lightglue import LightGlue as LG
|
hloc/matchers/roma.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
import subprocess
|
| 4 |
-
import logging
|
| 5 |
import torch
|
| 6 |
from PIL import Image
|
| 7 |
from ..utils.base_model import BaseModel
|
|
|
|
| 8 |
|
| 9 |
roma_path = Path(__file__).parent / "../../third_party/Roma"
|
| 10 |
sys.path.append(str(roma_path))
|
|
@@ -12,8 +12,6 @@ sys.path.append(str(roma_path))
|
|
| 12 |
from roma.models.model_zoo.roma_models import roma_model
|
| 13 |
|
| 14 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 15 |
-
logger = logging.getLogger(__name__)
|
| 16 |
-
|
| 17 |
|
| 18 |
class Roma(BaseModel):
|
| 19 |
default_conf = {
|
|
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
import subprocess
|
|
|
|
| 4 |
import torch
|
| 5 |
from PIL import Image
|
| 6 |
from ..utils.base_model import BaseModel
|
| 7 |
+
from .. import logger
|
| 8 |
|
| 9 |
roma_path = Path(__file__).parent / "../../third_party/Roma"
|
| 10 |
sys.path.append(str(roma_path))
|
|
|
|
| 12 |
from roma.models.model_zoo.roma_models import roma_model
|
| 13 |
|
| 14 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
|
|
|
|
|
| 15 |
|
| 16 |
class Roma(BaseModel):
|
| 17 |
default_conf = {
|
hloc/matchers/sgmnet.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
import subprocess
|
| 4 |
-
import logging
|
| 5 |
import torch
|
| 6 |
from PIL import Image
|
| 7 |
from collections import OrderedDict, namedtuple
|
| 8 |
from ..utils.base_model import BaseModel
|
| 9 |
from ..utils import do_system
|
|
|
|
| 10 |
|
| 11 |
sgmnet_path = Path(__file__).parent / "../../third_party/SGMNet"
|
| 12 |
sys.path.append(str(sgmnet_path))
|
|
@@ -14,7 +14,6 @@ sys.path.append(str(sgmnet_path))
|
|
| 14 |
from sgmnet import matcher as SGM_Model
|
| 15 |
|
| 16 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 17 |
-
logger = logging.getLogger(__name__)
|
| 18 |
|
| 19 |
|
| 20 |
class SGMNet(BaseModel):
|
|
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
import subprocess
|
|
|
|
| 4 |
import torch
|
| 5 |
from PIL import Image
|
| 6 |
from collections import OrderedDict, namedtuple
|
| 7 |
from ..utils.base_model import BaseModel
|
| 8 |
from ..utils import do_system
|
| 9 |
+
from .. import logger
|
| 10 |
|
| 11 |
sgmnet_path = Path(__file__).parent / "../../third_party/SGMNet"
|
| 12 |
sys.path.append(str(sgmnet_path))
|
|
|
|
| 14 |
from sgmnet import matcher as SGM_Model
|
| 15 |
|
| 16 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
|
|
| 17 |
|
| 18 |
|
| 19 |
class SGMNet(BaseModel):
|
hloc/matchers/sold2.py
CHANGED
|
@@ -4,18 +4,13 @@ from ..utils.base_model import BaseModel
|
|
| 4 |
import torch
|
| 5 |
|
| 6 |
from ..utils.base_model import BaseModel
|
|
|
|
|
|
|
| 7 |
|
| 8 |
sold2_path = Path(__file__).parent / "../../third_party/SOLD2"
|
| 9 |
sys.path.append(str(sold2_path))
|
| 10 |
|
| 11 |
from sold2.model.line_matcher import LineMatcher
|
| 12 |
-
from sold2.misc.visualize_util import (
|
| 13 |
-
plot_images,
|
| 14 |
-
plot_lines,
|
| 15 |
-
plot_line_matches,
|
| 16 |
-
plot_color_line_matches,
|
| 17 |
-
plot_keypoints,
|
| 18 |
-
)
|
| 19 |
|
| 20 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 21 |
|
|
@@ -36,9 +31,21 @@ class SOLD2(BaseModel):
|
|
| 36 |
"image1",
|
| 37 |
]
|
| 38 |
|
|
|
|
|
|
|
|
|
|
| 39 |
# Initialize the line matcher
|
| 40 |
def _init(self, conf):
|
| 41 |
checkpoint_path = conf["checkpoint_dir"] / conf["weights"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
mode = "dynamic" # 'dynamic' or 'static'
|
| 43 |
match_config = {
|
| 44 |
"model_cfg": {
|
|
|
|
| 4 |
import torch
|
| 5 |
|
| 6 |
from ..utils.base_model import BaseModel
|
| 7 |
+
from .. import logger
|
| 8 |
+
import subprocess
|
| 9 |
|
| 10 |
sold2_path = Path(__file__).parent / "../../third_party/SOLD2"
|
| 11 |
sys.path.append(str(sold2_path))
|
| 12 |
|
| 13 |
from sold2.model.line_matcher import LineMatcher
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 16 |
|
|
|
|
| 31 |
"image1",
|
| 32 |
]
|
| 33 |
|
| 34 |
+
weight_urls = {
|
| 35 |
+
"sold2_wireframe.tar": "https://www.polybox.ethz.ch/index.php/s/blOrW89gqSLoHOk/download",
|
| 36 |
+
}
|
| 37 |
# Initialize the line matcher
|
| 38 |
def _init(self, conf):
|
| 39 |
checkpoint_path = conf["checkpoint_dir"] / conf["weights"]
|
| 40 |
+
|
| 41 |
+
# Download the model.
|
| 42 |
+
if not checkpoint_path.exists():
|
| 43 |
+
checkpoint_path.parent.mkdir(exist_ok=True)
|
| 44 |
+
link = self.weight_urls[conf["weights"]]
|
| 45 |
+
cmd = ["wget", link, "-O", str(checkpoint_path)]
|
| 46 |
+
logger.info(f"Downloading the SOLD2 model with `{cmd}`.")
|
| 47 |
+
subprocess.run(cmd, check=True)
|
| 48 |
+
|
| 49 |
mode = "dynamic" # 'dynamic' or 'static'
|
| 50 |
match_config = {
|
| 51 |
"model_cfg": {
|
hloc/utils/__init__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
import os
|
| 2 |
import logging
|
| 3 |
-
|
| 4 |
-
|
| 5 |
|
| 6 |
|
| 7 |
def do_system(cmd, verbose=False):
|
|
|
|
| 1 |
import os
|
| 2 |
import logging
|
| 3 |
+
import sys
|
| 4 |
+
from .. import logger
|
| 5 |
|
| 6 |
|
| 7 |
def do_system(cmd, verbose=False):
|
third_party/RoRD/LICENSE
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License
|
| 2 |
+
|
| 3 |
+
By exercising the Licensed Rights (defined below), You accept and agree to be
|
| 4 |
+
bound by the terms and conditions of this Creative Commons
|
| 5 |
+
Attribution-NonCommercial-NoDerivatives 4.0 International Public License
|
| 6 |
+
("Public License"). To the extent this Public License may be interpreted as a
|
| 7 |
+
contract, You are granted the Licensed Rights in consideration of Your
|
| 8 |
+
acceptance of these terms and conditions, and the Licensor grants You such
|
| 9 |
+
rights in consideration of benefits the Licensor receives from making the
|
| 10 |
+
Licensed Material available under these terms and conditions.
|
| 11 |
+
|
| 12 |
+
Section 1 – Definitions.
|
| 13 |
+
|
| 14 |
+
a. Adapted Material means material subject to Copyright and Similar Rights
|
| 15 |
+
that is derived from or based upon the Licensed Material and in which
|
| 16 |
+
the Licensed Material is translated, altered, arranged, transformed, or
|
| 17 |
+
otherwise modified in a manner requiring permission under the Copyright
|
| 18 |
+
and Similar Rights held by the Licensor. For purposes of this Public
|
| 19 |
+
License, where the Licensed Material is a musical work, performance, or
|
| 20 |
+
sound recording, Adapted Material is always produced where the Licensed
|
| 21 |
+
Material is synched in timed relation with a moving image.
|
| 22 |
+
b. Copyright and Similar Rights means copyright and/or similar rights
|
| 23 |
+
closely related to copyright including, without limitation,
|
| 24 |
+
performance, broadcast, sound recording, and Sui Generis Database
|
| 25 |
+
Rights, without regard to how the rights are labeled or categorized.
|
| 26 |
+
For purposes of this Public License, the rights specified in Section
|
| 27 |
+
2(b)(1)-(2) are not Copyright and Similar Rights.
|
| 28 |
+
c. Effective Technological Measures means those measures that, in the
|
| 29 |
+
absence of proper authority, may not be circumvented under laws
|
| 30 |
+
fulfilling obligations under Article 11 of the WIPO Copyright Treaty
|
| 31 |
+
adopted on December 20, 1996, and/or similar international agreements.
|
| 32 |
+
d. Exceptions and Limitations means fair use, fair dealing, and/or any
|
| 33 |
+
other exception or limitation to Copyright and Similar Rights that
|
| 34 |
+
applies to Your use of the Licensed Material.
|
| 35 |
+
e. Licensed Material means the artistic or literary work, database, or
|
| 36 |
+
other material to which the Licensor applied this Public License.
|
| 37 |
+
f. Licensed Rights means the rights granted to You subject to the terms
|
| 38 |
+
and conditions of this Public License, which are limited to all
|
| 39 |
+
Copyright and Similar Rights that apply to Your use of the Licensed
|
| 40 |
+
Material and that the Licensor has authority to license.
|
| 41 |
+
g. Licensor means the individual(s) or entity(ies) granting rights under
|
| 42 |
+
this Public License.
|
| 43 |
+
h. NonCommercial means not primarily intended for or directed towards
|
| 44 |
+
commercial advantage or monetary compensation. For purposes of this
|
| 45 |
+
Public License, the exchange of the Licensed Material for other
|
| 46 |
+
material subject to Copyright and Similar Rights by digital
|
| 47 |
+
file-sharing or similar means is NonCommercial provided there is no
|
| 48 |
+
payment of monetary compensation in connection with the exchange.
|
| 49 |
+
i. Share means to provide material to the public by any means or process
|
| 50 |
+
that requires permission under the Licensed Rights, such as
|
| 51 |
+
reproduction, public display, public performance, distribution,
|
| 52 |
+
dissemination, communication, or importation, and to make material
|
| 53 |
+
available to the public including in ways that members of the public
|
| 54 |
+
may access the material from a place and at a time individually chosen
|
| 55 |
+
by them.
|
| 56 |
+
j. Sui Generis Database Rights means rights other than copyright resulting
|
| 57 |
+
from Directive 96/9/EC of the European Parliament and of the Council of
|
| 58 |
+
11 March 1996 on the legal protection of databases, as amended and/or
|
| 59 |
+
succeeded, as well as other essentially equivalent rights anywhere in
|
| 60 |
+
the world.
|
| 61 |
+
k. You means the individual or entity exercising the Licensed Rights under
|
| 62 |
+
this Public License. Your has a corresponding meaning.
|
| 63 |
+
|
| 64 |
+
Section 2 – Scope.
|
| 65 |
+
|
| 66 |
+
a. License grant.
|
| 67 |
+
1. Subject to the terms and conditions of this Public License, the
|
| 68 |
+
Licensor hereby grants You a worldwide, royalty-free,
|
| 69 |
+
non-sublicensable, non-exclusive, irrevocable license to exercise
|
| 70 |
+
the Licensed Rights in the Licensed Material to:
|
| 71 |
+
A. reproduce and Share the Licensed Material, in whole or in part,
|
| 72 |
+
for NonCommercial purposes only; and
|
| 73 |
+
B. produce and reproduce, but not Share, Adapted Material for
|
| 74 |
+
NonCommercial purposes only.
|
| 75 |
+
2. Exceptions and Limitations. For the avoidance of doubt, where
|
| 76 |
+
Exceptions and Limitations apply to Your use, this Public License
|
| 77 |
+
does not apply, and You do not need to comply with its terms and
|
| 78 |
+
conditions.
|
| 79 |
+
3. Term. The term of this Public License is specified in Section 6(a).
|
| 80 |
+
4. Media and formats; technical modifications allowed. The Licensor
|
| 81 |
+
authorizes You to exercise the Licensed Rights in all media and
|
| 82 |
+
formats whether now known or hereafter created, and to make
|
| 83 |
+
technical modifications necessary to do so. The Licensor waives
|
| 84 |
+
and/or agrees not to assert any right or authority to forbid You
|
| 85 |
+
from making technical modifications necessary to exercise the
|
| 86 |
+
Licensed Rights, including technical modifications necessary to
|
| 87 |
+
circumvent Effective Technological Measures. For purposes of this
|
| 88 |
+
Public License, simply making modifications authorized by this
|
| 89 |
+
Section 2(a)(4) never produces Adapted Material.
|
| 90 |
+
5. Downstream recipients.
|
| 91 |
+
A. Offer from the Licensor – Licensed Material. Every recipient of
|
| 92 |
+
the Licensed Material automatically receives an offer from the
|
| 93 |
+
Licensor to exercise the Licensed Rights under the terms and
|
| 94 |
+
conditions of this Public License.
|
| 95 |
+
B. No downstream restrictions. You may not offer or impose any
|
| 96 |
+
additional or different terms or conditions on, or apply any
|
| 97 |
+
Effective Technological Measures to, the Licensed Material if
|
| 98 |
+
doing so restricts exercise of the Licensed Rights by any
|
| 99 |
+
recipient of the Licensed Material.
|
| 100 |
+
6. No endorsement. Nothing in this Public License constitutes or may
|
| 101 |
+
be construed as permission to assert or imply that You are, or that
|
| 102 |
+
Your use of the Licensed Material is, connected with, or sponsored,
|
| 103 |
+
endorsed, or granted official status by, the Licensor or others
|
| 104 |
+
designated to receive attribution as provided in Section
|
| 105 |
+
3(a)(1)(A)(i).
|
| 106 |
+
|
| 107 |
+
b. Other rights.
|
| 108 |
+
1. Moral rights, such as the right of integrity, are not licensed
|
| 109 |
+
under this Public License, nor are publicity, privacy, and/or other
|
| 110 |
+
similar personality rights; however, to the extent possible, the
|
| 111 |
+
Licensor waives and/or agrees not to assert any such rights held by
|
| 112 |
+
the Licensor to the limited extent necessary to allow You to
|
| 113 |
+
exercise the Licensed Rights, but not otherwise.
|
| 114 |
+
2. Patent and trademark rights are not licensed under this Public
|
| 115 |
+
License.
|
| 116 |
+
3. To the extent possible, the Licensor waives any right to collect
|
| 117 |
+
royalties from You for the exercise of the Licensed Rights, whether
|
| 118 |
+
directly or through a collecting society under any voluntary or
|
| 119 |
+
waivable statutory or compulsory licensing scheme. In all other
|
| 120 |
+
cases the Licensor expressly reserves any right to collect such
|
| 121 |
+
royalties, including when the Licensed Material is used other than
|
| 122 |
+
for NonCommercial purposes.
|
| 123 |
+
|
| 124 |
+
Section 3 – License Conditions.
|
| 125 |
+
|
| 126 |
+
Your exercise of the Licensed Rights is expressly made subject to the following conditions.
|
| 127 |
+
|
| 128 |
+
a. Attribution.
|
| 129 |
+
|
| 130 |
+
1. If You Share the Licensed Material, You must:
|
| 131 |
+
A. retain the following if it is supplied by the Licensor with the
|
| 132 |
+
Licensed Material:
|
| 133 |
+
i. identification of the creator(s) of the Licensed Material
|
| 134 |
+
and any others designated to receive attribution, in any
|
| 135 |
+
reasonable manner requested by the Licensor (including by
|
| 136 |
+
pseudonym if designated);
|
| 137 |
+
ii. a copyright notice;
|
| 138 |
+
iii. a notice that refers to this Public License;
|
| 139 |
+
iv. a notice that refers to the disclaimer of warranties;
|
| 140 |
+
v. a URI or hyperlink to the Licensed Material to the extent
|
| 141 |
+
reasonably practicable;
|
| 142 |
+
B. indicate if You modified the Licensed Material and retain an
|
| 143 |
+
indication of any previous modifications; and
|
| 144 |
+
C. indicate the Licensed Material is licensed under this Public
|
| 145 |
+
License, and include the text of, or the URI or hyperlink to,
|
| 146 |
+
this Public License.
|
| 147 |
+
|
| 148 |
+
For the avoidance of doubt, You do not have permission under this
|
| 149 |
+
Public License to Share Adapted Material.
|
| 150 |
+
|
| 151 |
+
2. You may satisfy the conditions in Section 3(a)(1) in any reasonable
|
| 152 |
+
manner based on the medium, means, and context in which You Share
|
| 153 |
+
the Licensed Material. For example, it may be reasonable to satisfy
|
| 154 |
+
the conditions by providing a URI or hyperlink to a resource that
|
| 155 |
+
includes the required information.
|
| 156 |
+
3. If requested by the Licensor, You must remove any of the
|
| 157 |
+
information required by Section 3(a)(1)(A) to the extent reasonably
|
| 158 |
+
practicable.
|
| 159 |
+
|
| 160 |
+
Section 4 – Sui Generis Database Rights.
|
| 161 |
+
|
| 162 |
+
Where the Licensed Rights include Sui Generis Database Rights that apply to
|
| 163 |
+
Your use of the Licensed Material:
|
| 164 |
+
|
| 165 |
+
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to
|
| 166 |
+
extract, reuse, reproduce, and Share all or a substantial portion of
|
| 167 |
+
the contents of the database for NonCommercial purposes only and
|
| 168 |
+
provided You do not Share Adapted Material;
|
| 169 |
+
b. if You include all or a substantial portion of the database contents in
|
| 170 |
+
a database in which You have Sui Generis Database Rights, then the
|
| 171 |
+
database in which You have Sui Generis Database Rights (but not its
|
| 172 |
+
individual contents) is Adapted Material; and
|
| 173 |
+
c. You must comply with the conditions in Section 3(a) if You Share all or
|
| 174 |
+
a substantial portion of the contents of the database.
|
| 175 |
+
|
| 176 |
+
For the avoidance of doubt, this Section 4 supplements and does not replace
|
| 177 |
+
Your obligations under this Public License where the Licensed Rights include
|
| 178 |
+
other Copyright and Similar Rights.
|
| 179 |
+
|
| 180 |
+
Section 5 – Disclaimer of Warranties and Limitation of Liability.
|
| 181 |
+
|
| 182 |
+
a. Unless otherwise separately undertaken by the Licensor, to the extent
|
| 183 |
+
possible, the Licensor offers the Licensed Material as-is and
|
| 184 |
+
as-available, and makes no representations or warranties of any kind
|
| 185 |
+
concerning the Licensed Material, whether express, implied, statutory,
|
| 186 |
+
or other. This includes, without limitation, warranties of title,
|
| 187 |
+
merchantability, fitness for a particular purpose, non-infringement,
|
| 188 |
+
absence of latent or other defects, accuracy, or the presence or
|
| 189 |
+
absence of errors, whether or not known or discoverable. Where
|
| 190 |
+
disclaimers of warranties are not allowed in full or in part, this
|
| 191 |
+
disclaimer may not apply to You.
|
| 192 |
+
b. To the extent possible, in no event will the Licensor be liable to You
|
| 193 |
+
on any legal theory (including, without limitation, negligence) or
|
| 194 |
+
otherwise for any direct, special, indirect, incidental, consequential,
|
| 195 |
+
punitive, exemplary, or other losses, costs, expenses, or damages
|
| 196 |
+
arising out of this Public License or use of the Licensed Material,
|
| 197 |
+
even if the Licensor has been advised of the possibility of such
|
| 198 |
+
losses, costs, expenses, or damages. Where a limitation of liability is
|
| 199 |
+
not allowed in full or in part, this limitation may not apply to You.
|
| 200 |
+
c. The disclaimer of warranties and limitation of liability provided above
|
| 201 |
+
shall be interpreted in a manner that, to the extent possible, most
|
| 202 |
+
closely approximates an absolute disclaimer and waiver of all
|
| 203 |
+
liability.
|
| 204 |
+
|
| 205 |
+
Section 6 – Term and Termination.
|
| 206 |
+
|
| 207 |
+
a. This Public License applies for the term of the Copyright and Similar
|
| 208 |
+
Rights licensed here. However, if You fail to comply with this Public
|
| 209 |
+
License, then Your rights under this Public License terminate
|
| 210 |
+
automatically.
|
| 211 |
+
b. Where Your right to use the Licensed Material has terminated under
|
| 212 |
+
Section 6(a), it reinstates:
|
| 213 |
+
1. automatically as of the date the violation is cured, provided it is
|
| 214 |
+
cured within 30 days of Your discovery of the violation; or
|
| 215 |
+
2. upon express reinstatement by the Licensor.
|
| 216 |
+
|
| 217 |
+
For the avoidance of doubt, this Section 6(b) does not affect any right
|
| 218 |
+
the Licensor may have to seek remedies for Your violations of this
|
| 219 |
+
Public License.
|
| 220 |
+
|
| 221 |
+
c. For the avoidance of doubt, the Licensor may also offer the Licensed
|
| 222 |
+
Material under separate terms or conditions or stop distributing the
|
| 223 |
+
Licensed Material at any time; however, doing so will not terminate
|
| 224 |
+
this Public License.
|
| 225 |
+
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
|
| 226 |
+
|
| 227 |
+
Section 7 – Other Terms and Conditions.
|
| 228 |
+
|
| 229 |
+
a. The Licensor shall not be bound by any additional or different terms or
|
| 230 |
+
conditions communicated by You unless expressly agreed.
|
| 231 |
+
b. Any arrangements, understandings, or agreements regarding the Licensed
|
| 232 |
+
Material not stated herein are separate from and independent of the
|
| 233 |
+
terms and conditions of this Public License.
|
| 234 |
+
|
| 235 |
+
Section 8 – Interpretation.
|
| 236 |
+
|
| 237 |
+
a. For the avoidance of doubt, this Public License does not, and shall not
|
| 238 |
+
be interpreted to, reduce, limit, restrict, or impose conditions on any
|
| 239 |
+
use of the Licensed Material that could lawfully be made without
|
| 240 |
+
permission under this Public License.
|
| 241 |
+
b. To the extent possible, if any provision of this Public License is
|
| 242 |
+
deemed unenforceable, it shall be automatically reformed to the minimum
|
| 243 |
+
extent necessary to make it enforceable. If the provision cannot be
|
| 244 |
+
reformed, it shall be severed from this Public License without
|
| 245 |
+
affecting the enforceability of the remaining terms and conditions.
|
| 246 |
+
c. No term or condition of this Public License will be waived and no
|
| 247 |
+
failure to comply consented to unless expressly agreed to by the Licensor.
|
| 248 |
+
d. Nothing in this Public License constitutes or may be interpreted as a
|
| 249 |
+
limitation upon, or waiver of, any privileges and immunities that apply
|
| 250 |
+
to the Licensor or You, including from the legal processes of any
|
| 251 |
+
jurisdiction or authority.
|
third_party/RoRD/assets/register_ortho.jpg
ADDED
|
Git LFS Details
|
third_party/RoRD/assets/register_persp.jpg
ADDED
|
Git LFS Details
|
third_party/RoRD/assets/register_pointcloud.jpg
ADDED
|
Git LFS Details
|
third_party/RoRD/assets/rord_evalRT.jpg
ADDED
|
Git LFS Details
|
third_party/RoRD/assets/rord_extract.jpg
ADDED
|
Git LFS Details
|
third_party/RoRD/assets/sift_extract.jpg
ADDED
|
Git LFS Details
|
third_party/RoRD/assets/teaser2.jpg
ADDED
|
Git LFS Details
|
third_party/RoRD/configs/camera.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
382.1996765136719 381.8395690917969 312.7102355957031 247.72047424316406 1000.0
|
| 2 |
+
|
| 3 |
+
|
third_party/RoRD/configs/train_scenes.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
temple_nara_japan
|
| 2 |
+
brandenburg_gate
|
| 3 |
+
taj_mahal
|
| 4 |
+
buckingham_palace
|
| 5 |
+
grand_place_brussels
|
| 6 |
+
hagia_sophia_interior
|
| 7 |
+
westminster_abbey
|
third_party/RoRD/configs/train_scenes_small.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
brandenburg_gate
|
third_party/RoRD/demo/__init__.py
ADDED
|
File without changes
|
third_party/RoRD/demo/depth/depth1_1.png
ADDED
|
Git LFS Details
|
third_party/RoRD/demo/depth/depth1_2.png
ADDED
|
Git LFS Details
|
third_party/RoRD/demo/depth/depth2_1.png
ADDED
|
Git LFS Details
|
third_party/RoRD/demo/depth/depth2_2.png
ADDED
|
Git LFS Details
|
third_party/RoRD/demo/depth/depth3_1.png
ADDED
|
Git LFS Details
|
third_party/RoRD/demo/depth/depth3_2.png
ADDED
|
Git LFS Details
|
third_party/RoRD/demo/register.py
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
import copy
|
| 3 |
+
import argparse
|
| 4 |
+
import os, sys
|
| 5 |
+
import open3d as o3d
|
| 6 |
+
from sys import argv
|
| 7 |
+
from PIL import Image
|
| 8 |
+
import math
|
| 9 |
+
import cv2
|
| 10 |
+
import torch
|
| 11 |
+
|
| 12 |
+
sys.path.append("../")
|
| 13 |
+
from lib.extractMatchTop import getPerspKeypoints, getPerspKeypointsEnsemble, siftMatching
|
| 14 |
+
from lib.model_test import D2Net
|
| 15 |
+
|
| 16 |
+
#### Cuda ####
|
| 17 |
+
use_cuda = torch.cuda.is_available()
|
| 18 |
+
device = torch.device('cuda:0' if use_cuda else 'cpu')
|
| 19 |
+
|
| 20 |
+
#### Argument Parsing ####
|
| 21 |
+
parser = argparse.ArgumentParser(description='RoRD ICP evaluation')
|
| 22 |
+
|
| 23 |
+
parser.add_argument(
|
| 24 |
+
'--rgb1', type=str, default = 'rgb/rgb2_1.jpg',
|
| 25 |
+
help='path to the rgb image1'
|
| 26 |
+
)
|
| 27 |
+
parser.add_argument(
|
| 28 |
+
'--rgb2', type=str, default = 'rgb/rgb2_2.jpg',
|
| 29 |
+
help='path to the rgb image2'
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
parser.add_argument(
|
| 33 |
+
'--depth1', type=str, default = 'depth/depth2_1.png',
|
| 34 |
+
help='path to the depth image1'
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
parser.add_argument(
|
| 38 |
+
'--depth2', type=str, default = 'depth/depth2_2.png',
|
| 39 |
+
help='path to the depth image2'
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
parser.add_argument(
|
| 43 |
+
'--model_rord', type=str, default = '../models/rord.pth',
|
| 44 |
+
help='path to the RoRD model for evaluation'
|
| 45 |
+
)
|
| 46 |
+
|
| 47 |
+
parser.add_argument(
|
| 48 |
+
'--model_d2', type=str,
|
| 49 |
+
help='path to the vanilla D2-Net model for evaluation'
|
| 50 |
+
)
|
| 51 |
+
|
| 52 |
+
parser.add_argument(
|
| 53 |
+
'--model_ens', action='store_true',
|
| 54 |
+
help='ensemble model of RoRD + D2-Net'
|
| 55 |
+
)
|
| 56 |
+
|
| 57 |
+
parser.add_argument(
|
| 58 |
+
'--sift', action='store_true',
|
| 59 |
+
help='Sift'
|
| 60 |
+
)
|
| 61 |
+
|
| 62 |
+
parser.add_argument(
|
| 63 |
+
'--camera_file', type=str, default='../configs/camera.txt',
|
| 64 |
+
help='path to the camera intrinsics file. In order: focal_x, focal_y, center_x, center_y, scaling_factor.'
|
| 65 |
+
)
|
| 66 |
+
|
| 67 |
+
parser.add_argument(
|
| 68 |
+
'--viz3d', action='store_true',
|
| 69 |
+
help='visualize the pointcloud registrations'
|
| 70 |
+
)
|
| 71 |
+
|
| 72 |
+
args = parser.parse_args()
|
| 73 |
+
|
| 74 |
+
if args.model_ens: # Change default paths accordingly for ensemble
|
| 75 |
+
model1_ens = '../../models/rord.pth'
|
| 76 |
+
model2_ens = '../../models/d2net.pth'
|
| 77 |
+
|
| 78 |
+
def draw_registration_result(source, target, transformation):
|
| 79 |
+
source_temp = copy.deepcopy(source)
|
| 80 |
+
target_temp = copy.deepcopy(target)
|
| 81 |
+
source_temp.transform(transformation)
|
| 82 |
+
|
| 83 |
+
target_temp += source_temp
|
| 84 |
+
# print("Saved registered PointCloud.")
|
| 85 |
+
# o3d.io.write_point_cloud("registered.pcd", target_temp)
|
| 86 |
+
|
| 87 |
+
trgSph.append(source_temp); trgSph.append(target_temp)
|
| 88 |
+
axis1 = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.5, origin=[0, 0, 0])
|
| 89 |
+
axis2 = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.5, origin=[0, 0, 0])
|
| 90 |
+
axis2.transform(transformation)
|
| 91 |
+
trgSph.append(axis1); trgSph.append(axis2)
|
| 92 |
+
print("Showing registered PointCloud.")
|
| 93 |
+
o3d.visualization.draw_geometries(trgSph)
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def readDepth(depthFile):
|
| 97 |
+
depth = Image.open(depthFile)
|
| 98 |
+
if depth.mode != "I":
|
| 99 |
+
raise Exception("Depth image is not in intensity format")
|
| 100 |
+
|
| 101 |
+
return np.asarray(depth)
|
| 102 |
+
|
| 103 |
+
def readCamera(camera):
|
| 104 |
+
with open (camera, "rt") as file:
|
| 105 |
+
contents = file.read().split()
|
| 106 |
+
|
| 107 |
+
focalX = float(contents[0])
|
| 108 |
+
focalY = float(contents[1])
|
| 109 |
+
centerX = float(contents[2])
|
| 110 |
+
centerY = float(contents[3])
|
| 111 |
+
scalingFactor = float(contents[4])
|
| 112 |
+
|
| 113 |
+
return focalX, focalY, centerX, centerY, scalingFactor
|
| 114 |
+
|
| 115 |
+
def getPointCloud(rgbFile, depthFile, pts):
|
| 116 |
+
thresh = 15.0
|
| 117 |
+
|
| 118 |
+
depth = readDepth(depthFile)
|
| 119 |
+
rgb = Image.open(rgbFile)
|
| 120 |
+
|
| 121 |
+
points = []
|
| 122 |
+
colors = []
|
| 123 |
+
|
| 124 |
+
corIdx = [-1]*len(pts)
|
| 125 |
+
corPts = [None]*len(pts)
|
| 126 |
+
ptIdx = 0
|
| 127 |
+
|
| 128 |
+
for v in range(depth.shape[0]):
|
| 129 |
+
for u in range(depth.shape[1]):
|
| 130 |
+
Z = depth[v, u] / scalingFactor
|
| 131 |
+
if Z==0: continue
|
| 132 |
+
if (Z > thresh): continue
|
| 133 |
+
|
| 134 |
+
X = (u - centerX) * Z / focalX
|
| 135 |
+
Y = (v - centerY) * Z / focalY
|
| 136 |
+
|
| 137 |
+
points.append((X, Y, Z))
|
| 138 |
+
colors.append(rgb.getpixel((u, v)))
|
| 139 |
+
|
| 140 |
+
if((u, v) in pts):
|
| 141 |
+
# print("Point found.")
|
| 142 |
+
index = pts.index((u, v))
|
| 143 |
+
corIdx[index] = ptIdx
|
| 144 |
+
corPts[index] = (X, Y, Z)
|
| 145 |
+
|
| 146 |
+
ptIdx = ptIdx+1
|
| 147 |
+
|
| 148 |
+
points = np.asarray(points)
|
| 149 |
+
colors = np.asarray(colors)
|
| 150 |
+
|
| 151 |
+
pcd = o3d.geometry.PointCloud()
|
| 152 |
+
pcd.points = o3d.utility.Vector3dVector(points)
|
| 153 |
+
pcd.colors = o3d.utility.Vector3dVector(colors/255)
|
| 154 |
+
|
| 155 |
+
return pcd, corIdx, corPts
|
| 156 |
+
|
| 157 |
+
|
| 158 |
+
def convertPts(A):
|
| 159 |
+
X = A[0]; Y = A[1]
|
| 160 |
+
|
| 161 |
+
x = []; y = []
|
| 162 |
+
|
| 163 |
+
for i in range(len(X)):
|
| 164 |
+
x.append(int(float(X[i])))
|
| 165 |
+
|
| 166 |
+
for i in range(len(Y)):
|
| 167 |
+
y.append(int(float(Y[i])))
|
| 168 |
+
|
| 169 |
+
pts = []
|
| 170 |
+
for i in range(len(x)):
|
| 171 |
+
pts.append((x[i], y[i]))
|
| 172 |
+
|
| 173 |
+
return pts
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
def getSphere(pts):
|
| 177 |
+
sphs = []
|
| 178 |
+
|
| 179 |
+
for ele in pts:
|
| 180 |
+
if(ele is not None):
|
| 181 |
+
sphere = o3d.geometry.TriangleMesh.create_sphere(radius=0.03)
|
| 182 |
+
sphere.paint_uniform_color([0.9, 0.2, 0])
|
| 183 |
+
|
| 184 |
+
trans = np.identity(4)
|
| 185 |
+
trans[0, 3] = ele[0]
|
| 186 |
+
trans[1, 3] = ele[1]
|
| 187 |
+
trans[2, 3] = ele[2]
|
| 188 |
+
|
| 189 |
+
sphere.transform(trans)
|
| 190 |
+
sphs.append(sphere)
|
| 191 |
+
|
| 192 |
+
return sphs
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
def get3dCor(src, trg):
|
| 196 |
+
corr = []
|
| 197 |
+
|
| 198 |
+
for sId, tId in zip(src, trg):
|
| 199 |
+
if(sId != -1 and tId != -1):
|
| 200 |
+
corr.append((sId, tId))
|
| 201 |
+
|
| 202 |
+
corr = np.asarray(corr)
|
| 203 |
+
|
| 204 |
+
return corr
|
| 205 |
+
|
| 206 |
+
if __name__ == "__main__":
|
| 207 |
+
|
| 208 |
+
focalX, focalY, centerX, centerY, scalingFactor = readCamera(args.camera_file)
|
| 209 |
+
|
| 210 |
+
rgb_name_src = os.path.basename(args.rgb1)
|
| 211 |
+
H_name_src = os.path.splitext(rgb_name_src)[0] + '.npy'
|
| 212 |
+
srcH = os.path.join(os.path.dirname(args.rgb1), H_name_src)
|
| 213 |
+
rgb_name_trg = os.path.basename(args.rgb2)
|
| 214 |
+
H_name_trg = os.path.splitext(rgb_name_trg)[0] + '.npy'
|
| 215 |
+
trgH = os.path.join(os.path.dirname(args.rgb2), H_name_trg)
|
| 216 |
+
|
| 217 |
+
use_cuda = torch.cuda.is_available()
|
| 218 |
+
device = torch.device('cuda:0' if use_cuda else 'cpu')
|
| 219 |
+
model1 = D2Net(model_file=args.model_d2)
|
| 220 |
+
model1 = model1.to(device)
|
| 221 |
+
model2 = D2Net(model_file=args.model_rord)
|
| 222 |
+
model2 = model2.to(device)
|
| 223 |
+
|
| 224 |
+
if args.model_rord:
|
| 225 |
+
srcPts, trgPts, matchImg, matchImgOrtho = getPerspKeypoints(args.rgb1, args.rgb2, srcH, trgH, model2, device)
|
| 226 |
+
elif args.model_d2:
|
| 227 |
+
srcPts, trgPts, matchImg, matchImgOrtho = getPerspKeypoints(args.rgb1, args.rgb2, srcH, trgH, model1, device)
|
| 228 |
+
elif args.model_ens:
|
| 229 |
+
model1 = D2Net(model_file=model1_ens)
|
| 230 |
+
model1 = model1.to(device)
|
| 231 |
+
model2 = D2Net(model_file=model2_ens)
|
| 232 |
+
model2 = model2.to(device)
|
| 233 |
+
srcPts, trgPts, matchImg, matchImgOrtho = getPerspKeypointsEnsemble(model1, model2, args.rgb1, args.rgb2, srcH, trgH, device)
|
| 234 |
+
elif args.sift:
|
| 235 |
+
srcPts, trgPts, matchImg, matchImgOrtho = siftMatching(args.rgb1, args.rgb2, srcH, trgH, device)
|
| 236 |
+
|
| 237 |
+
#### Visualization ####
|
| 238 |
+
print("\nShowing matches in perspective and orthographic view. Press q\n")
|
| 239 |
+
cv2.imshow('Orthographic view', matchImgOrtho)
|
| 240 |
+
cv2.imshow('Perspective view', matchImg)
|
| 241 |
+
cv2.waitKey()
|
| 242 |
+
|
| 243 |
+
srcPts = convertPts(srcPts)
|
| 244 |
+
trgPts = convertPts(trgPts)
|
| 245 |
+
|
| 246 |
+
srcCld, srcIdx, srcCor = getPointCloud(args.rgb1, args.depth1, srcPts)
|
| 247 |
+
trgCld, trgIdx, trgCor = getPointCloud(args.rgb2, args.depth2, trgPts)
|
| 248 |
+
|
| 249 |
+
srcSph = getSphere(srcCor)
|
| 250 |
+
trgSph = getSphere(trgCor)
|
| 251 |
+
axis = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.5, origin=[0, 0, 0])
|
| 252 |
+
srcSph.append(srcCld); srcSph.append(axis)
|
| 253 |
+
trgSph.append(trgCld); trgSph.append(axis)
|
| 254 |
+
|
| 255 |
+
corr = get3dCor(srcIdx, trgIdx)
|
| 256 |
+
|
| 257 |
+
p2p = o3d.registration.TransformationEstimationPointToPoint()
|
| 258 |
+
trans_init = p2p.compute_transformation(srcCld, trgCld, o3d.utility.Vector2iVector(corr))
|
| 259 |
+
print("Transformation matrix: \n", trans_init)
|
| 260 |
+
|
| 261 |
+
if args.viz3d:
|
| 262 |
+
# o3d.visualization.draw_geometries(srcSph)
|
| 263 |
+
# o3d.visualization.draw_geometries(trgSph)
|
| 264 |
+
|
| 265 |
+
draw_registration_result(srcCld, trgCld, trans_init)
|
third_party/RoRD/demo/rgb/rgb1_1.jpg
ADDED
|
Git LFS Details
|
third_party/RoRD/demo/rgb/rgb1_1.npy
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:99396bb9e7c265b8bad5237806d37d8fd9d92a772e118f6de22668f1db011948
|
| 3 |
+
size 200
|
third_party/RoRD/demo/rgb/rgb1_2.jpg
ADDED
|
Git LFS Details
|
third_party/RoRD/demo/rgb/rgb1_2.npy
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f29bb750adcb50b497192ecbd554cf3cd74c3f1c9809d41994c5acd1654179f2
|
| 3 |
+
size 200
|
third_party/RoRD/demo/rgb/rgb2_1.jpg
ADDED
|
Git LFS Details
|
third_party/RoRD/demo/rgb/rgb2_1.npy
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0b911f2c3962789f99f31fc78313262ec3fa257b9dd8887d318f69fa7a303c04
|
| 3 |
+
size 200
|
third_party/RoRD/demo/rgb/rgb2_2.jpg
ADDED
|
Git LFS Details
|
third_party/RoRD/demo/rgb/rgb2_2.npy
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:63b82950927db25768fe129af2138f535faf3da2789c87e7c98957c90d8423f2
|
| 3 |
+
size 200
|
third_party/RoRD/demo/rgb/rgb3_1.jpg
ADDED
|
Git LFS Details
|
third_party/RoRD/demo/rgb/rgb3_1.npy
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d3262c4ce815dad042112aed3f3a082806fc3dab62ee6bd02492ec94abbf6987
|
| 3 |
+
size 200
|
third_party/RoRD/demo/rgb/rgb3_2.jpg
ADDED
|
Git LFS Details
|