Spaces:
Sleeping
Sleeping
Realcat
commited on
Commit
•
f90241e
1
Parent(s):
2134b25
add: mast3r
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- common/config.yaml +11 -0
- hloc/match_dense.py +14 -0
- hloc/matchers/mast3r.py +113 -0
- third_party/mast3r/.gitignore +129 -0
- third_party/mast3r/.gitmodules +4 -0
- third_party/mast3r/CHECKPOINTS_NOTICE +1376 -0
- third_party/mast3r/LICENSE +7 -0
- third_party/mast3r/NOTICE +103 -0
- third_party/mast3r/README.md +316 -0
- third_party/mast3r/assets/NLE_tower/01D90321-69C8-439F-B0B0-E87E7634741C-83120-000041DAE419D7AE.jpg +3 -0
- third_party/mast3r/assets/NLE_tower/1AD85EF5-B651-4291-A5C0-7BDB7D966384-83120-000041DADF639E09.jpg +3 -0
- third_party/mast3r/assets/NLE_tower/2679C386-1DC0-4443-81B5-93D7EDE4AB37-83120-000041DADB2EA917.jpg +3 -0
- third_party/mast3r/assets/NLE_tower/28EDBB63-B9F9-42FB-AC86-4852A33ED71B-83120-000041DAF22407A1.jpg +3 -0
- third_party/mast3r/assets/NLE_tower/91E9B685-7A7D-42D7-B933-23A800EE4129-83120-000041DAE12C8176.jpg +3 -0
- third_party/mast3r/assets/NLE_tower/CDBBD885-54C3-4EB4-9181-226059A60EE0-83120-000041DAE0C3D612.jpg +3 -0
- third_party/mast3r/assets/NLE_tower/FF5599FD-768B-431A-AB83-BDA5FB44CB9D-83120-000041DADDE35483.jpg +3 -0
- third_party/mast3r/assets/demo.jpg +3 -0
- third_party/mast3r/assets/examples.jpg +3 -0
- third_party/mast3r/assets/mast3r.jpg +3 -0
- third_party/mast3r/assets/mast3r_archi.jpg +3 -0
- third_party/mast3r/assets/matching.jpg +3 -0
- third_party/mast3r/demo.py +290 -0
- third_party/mast3r/demo_dust3r_ga.py +64 -0
- third_party/mast3r/dust3r/.gitignore +132 -0
- third_party/mast3r/dust3r/.gitmodules +3 -0
- third_party/mast3r/dust3r/LICENSE +7 -0
- third_party/mast3r/dust3r/NOTICE +12 -0
- third_party/mast3r/dust3r/README.md +388 -0
- third_party/mast3r/dust3r/assets/demo.jpg +3 -0
- third_party/mast3r/dust3r/assets/dust3r.jpg +3 -0
- third_party/mast3r/dust3r/assets/dust3r_archi.jpg +3 -0
- third_party/mast3r/dust3r/assets/matching.jpg +3 -0
- third_party/mast3r/dust3r/assets/pipeline1.jpg +3 -0
- third_party/mast3r/dust3r/croco/LICENSE +52 -0
- third_party/mast3r/dust3r/croco/NOTICE +21 -0
- third_party/mast3r/dust3r/croco/README.MD +124 -0
- third_party/mast3r/dust3r/croco/assets/Chateau1.png +3 -0
- third_party/mast3r/dust3r/croco/assets/Chateau2.png +3 -0
- third_party/mast3r/dust3r/croco/assets/arch.jpg +3 -0
- third_party/mast3r/dust3r/croco/croco-stereo-flow-demo.ipynb +191 -0
- third_party/mast3r/dust3r/croco/datasets/__init__.py +0 -0
- third_party/mast3r/dust3r/croco/datasets/crops/README.MD +104 -0
- third_party/mast3r/dust3r/croco/datasets/crops/extract_crops_from_images.py +159 -0
- third_party/mast3r/dust3r/croco/datasets/habitat_sim/README.MD +76 -0
- third_party/mast3r/dust3r/croco/datasets/habitat_sim/__init__.py +0 -0
- third_party/mast3r/dust3r/croco/datasets/habitat_sim/generate_from_metadata.py +92 -0
- third_party/mast3r/dust3r/croco/datasets/habitat_sim/generate_from_metadata_files.py +27 -0
- third_party/mast3r/dust3r/croco/datasets/habitat_sim/generate_multiview_images.py +177 -0
- third_party/mast3r/dust3r/croco/datasets/habitat_sim/multiview_habitat_sim_generator.py +390 -0
- third_party/mast3r/dust3r/croco/datasets/habitat_sim/pack_metadata_files.py +69 -0
common/config.yaml
CHANGED
@@ -27,6 +27,17 @@ matcher_zoo:
|
|
27 |
paper: https://arxiv.org/abs/2405.12979
|
28 |
project: https://hwjiang1510.github.io/OmniGlue
|
29 |
display: true
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
DUSt3R:
|
31 |
# TODO: duster is under development
|
32 |
enable: true
|
|
|
27 |
paper: https://arxiv.org/abs/2405.12979
|
28 |
project: https://hwjiang1510.github.io/OmniGlue
|
29 |
display: true
|
30 |
+
Mast3R:
|
31 |
+
enable: false
|
32 |
+
matcher: mast3r
|
33 |
+
dense: true
|
34 |
+
info:
|
35 |
+
name: Mast3R #dispaly name
|
36 |
+
source: "CVPR 2024"
|
37 |
+
github: https://github.com/naver/mast3r
|
38 |
+
paper: https://arxiv.org/abs/2312.14132
|
39 |
+
project: https://dust3r.europe.naverlabs.com
|
40 |
+
display: true
|
41 |
DUSt3R:
|
42 |
# TODO: duster is under development
|
43 |
enable: true
|
hloc/match_dense.py
CHANGED
@@ -144,6 +144,20 @@ confs = {
|
|
144 |
"dfactor": 16,
|
145 |
},
|
146 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
"xfeat_dense": {
|
148 |
"output": "matches-xfeat_dense",
|
149 |
"model": {
|
|
|
144 |
"dfactor": 16,
|
145 |
},
|
146 |
},
|
147 |
+
"mast3r": {
|
148 |
+
"output": "matches-mast3r",
|
149 |
+
"model": {
|
150 |
+
"name": "mast3r",
|
151 |
+
"weights": "vit_large",
|
152 |
+
"max_keypoints": 2000,
|
153 |
+
"match_threshold": 0.2,
|
154 |
+
},
|
155 |
+
"preprocessing": {
|
156 |
+
"grayscale": False,
|
157 |
+
"resize_max": 512,
|
158 |
+
"dfactor": 16,
|
159 |
+
},
|
160 |
+
},
|
161 |
"xfeat_dense": {
|
162 |
"output": "matches-xfeat_dense",
|
163 |
"model": {
|
hloc/matchers/mast3r.py
ADDED
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import sys
|
3 |
+
import urllib.request
|
4 |
+
from pathlib import Path
|
5 |
+
|
6 |
+
import numpy as np
|
7 |
+
import torch
|
8 |
+
import torchvision.transforms as tfm
|
9 |
+
|
10 |
+
from .. import logger
|
11 |
+
from ..utils.base_model import BaseModel
|
12 |
+
|
13 |
+
mast3r_path = Path(__file__).parent / "../../third_party/mast3r"
|
14 |
+
sys.path.append(str(mast3r_path))
|
15 |
+
|
16 |
+
dust3r_path = Path(__file__).parent / "../../third_party/dust3r"
|
17 |
+
sys.path.append(str(dust3r_path))
|
18 |
+
|
19 |
+
from mast3r.model import AsymmetricMASt3R
|
20 |
+
from mast3r.fast_nn import fast_reciprocal_NNs
|
21 |
+
|
22 |
+
from dust3r.image_pairs import make_pairs
|
23 |
+
from dust3r.inference import inference
|
24 |
+
from dust3r.utils.image import load_images
|
25 |
+
from hloc.matchers.duster import Duster
|
26 |
+
|
27 |
+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
28 |
+
|
29 |
+
|
30 |
+
class Mast3r(Duster):
|
31 |
+
default_conf = {
|
32 |
+
"name": "Mast3r",
|
33 |
+
"model_path": mast3r_path
|
34 |
+
/ "model_weights/MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric.pth",
|
35 |
+
"max_keypoints": 2000,
|
36 |
+
"vit_patch_size": 16,
|
37 |
+
}
|
38 |
+
|
39 |
+
def _init(self, conf):
|
40 |
+
self.normalize = tfm.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
|
41 |
+
self.model_path = self.conf["model_path"]
|
42 |
+
self.download_weights()
|
43 |
+
self.net = AsymmetricMASt3R.from_pretrained(self.model_path).to(device)
|
44 |
+
logger.info("Loaded Mast3r model")
|
45 |
+
|
46 |
+
def download_weights(self):
|
47 |
+
url = "https://download.europe.naverlabs.com/ComputerVision/MASt3R/MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric.pth"
|
48 |
+
|
49 |
+
self.model_path.parent.mkdir(parents=True, exist_ok=True)
|
50 |
+
if not os.path.isfile(self.model_path):
|
51 |
+
logger.info("Downloading Mast3r(ViT large)... (takes a while)")
|
52 |
+
urllib.request.urlretrieve(url, self.model_path)
|
53 |
+
logger.info("Downloading Mast3r(ViT large)... done!")
|
54 |
+
|
55 |
+
def _forward(self, data):
|
56 |
+
img0, img1 = data["image0"], data["image1"]
|
57 |
+
mean = torch.tensor([0.5, 0.5, 0.5]).to(device)
|
58 |
+
std = torch.tensor([0.5, 0.5, 0.5]).to(device)
|
59 |
+
|
60 |
+
img0 = (img0 - mean.view(1, 3, 1, 1)) / std.view(1, 3, 1, 1)
|
61 |
+
img1 = (img1 - mean.view(1, 3, 1, 1)) / std.view(1, 3, 1, 1)
|
62 |
+
|
63 |
+
images = [
|
64 |
+
{"img": img0, "idx": 0, "instance": 0},
|
65 |
+
{"img": img1, "idx": 1, "instance": 1},
|
66 |
+
]
|
67 |
+
pairs = make_pairs(
|
68 |
+
images, scene_graph="complete", prefilter=None, symmetrize=True
|
69 |
+
)
|
70 |
+
output = inference(pairs, self.net, device, batch_size=1)
|
71 |
+
|
72 |
+
# at this stage, you have the raw dust3r predictions
|
73 |
+
view1, pred1 = output["view1"], output["pred1"]
|
74 |
+
view2, pred2 = output["view2"], output["pred2"]
|
75 |
+
|
76 |
+
desc1, desc2 = (
|
77 |
+
pred1["desc"][1].squeeze(0).detach(),
|
78 |
+
pred2["desc"][1].squeeze(0).detach(),
|
79 |
+
)
|
80 |
+
|
81 |
+
# find 2D-2D matches between the two images
|
82 |
+
matches_im0, matches_im1 = fast_reciprocal_NNs(
|
83 |
+
desc1,
|
84 |
+
desc2,
|
85 |
+
subsample_or_initxy1=2,
|
86 |
+
device=device,
|
87 |
+
dist="dot",
|
88 |
+
block_size=2**13,
|
89 |
+
)
|
90 |
+
|
91 |
+
mkpts0 = matches_im0.copy()
|
92 |
+
mkpts1 = matches_im1.copy()
|
93 |
+
|
94 |
+
if len(mkpts0) == 0:
|
95 |
+
pred = {
|
96 |
+
"keypoints0": torch.zeros([0, 2]),
|
97 |
+
"keypoints1": torch.zeros([0, 2]),
|
98 |
+
}
|
99 |
+
logger.warning(f"Matched {0} points")
|
100 |
+
else:
|
101 |
+
|
102 |
+
top_k = self.conf["max_keypoints"]
|
103 |
+
if top_k is not None and len(mkpts0) > top_k:
|
104 |
+
keep = np.round(np.linspace(0, len(mkpts0) - 1, top_k)).astype(
|
105 |
+
int
|
106 |
+
)
|
107 |
+
mkpts0 = mkpts0[keep]
|
108 |
+
mkpts1 = mkpts1[keep]
|
109 |
+
pred = {
|
110 |
+
"keypoints0": torch.from_numpy(mkpts0),
|
111 |
+
"keypoints1": torch.from_numpy(mkpts1),
|
112 |
+
}
|
113 |
+
return pred
|
third_party/mast3r/.gitignore
ADDED
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Byte-compiled / optimized / DLL files
|
2 |
+
__pycache__/
|
3 |
+
*.py[cod]
|
4 |
+
*$py.class
|
5 |
+
|
6 |
+
# C extensions
|
7 |
+
*.so
|
8 |
+
|
9 |
+
# Distribution / packaging
|
10 |
+
.Python
|
11 |
+
build/
|
12 |
+
develop-eggs/
|
13 |
+
dist/
|
14 |
+
downloads/
|
15 |
+
eggs/
|
16 |
+
.eggs/
|
17 |
+
lib/
|
18 |
+
lib64/
|
19 |
+
parts/
|
20 |
+
sdist/
|
21 |
+
var/
|
22 |
+
wheels/
|
23 |
+
pip-wheel-metadata/
|
24 |
+
share/python-wheels/
|
25 |
+
*.egg-info/
|
26 |
+
.installed.cfg
|
27 |
+
*.egg
|
28 |
+
MANIFEST
|
29 |
+
|
30 |
+
# PyInstaller
|
31 |
+
# Usually these files are written by a python script from a template
|
32 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
33 |
+
*.manifest
|
34 |
+
*.spec
|
35 |
+
|
36 |
+
# Installer logs
|
37 |
+
pip-log.txt
|
38 |
+
pip-delete-this-directory.txt
|
39 |
+
|
40 |
+
# Unit test / coverage reports
|
41 |
+
htmlcov/
|
42 |
+
.tox/
|
43 |
+
.nox/
|
44 |
+
.coverage
|
45 |
+
.coverage.*
|
46 |
+
.cache
|
47 |
+
nosetests.xml
|
48 |
+
coverage.xml
|
49 |
+
*.cover
|
50 |
+
*.py,cover
|
51 |
+
.hypothesis/
|
52 |
+
.pytest_cache/
|
53 |
+
|
54 |
+
# Translations
|
55 |
+
*.mo
|
56 |
+
*.pot
|
57 |
+
|
58 |
+
# Django stuff:
|
59 |
+
*.log
|
60 |
+
local_settings.py
|
61 |
+
db.sqlite3
|
62 |
+
db.sqlite3-journal
|
63 |
+
|
64 |
+
# Flask stuff:
|
65 |
+
instance/
|
66 |
+
.webassets-cache
|
67 |
+
|
68 |
+
# Scrapy stuff:
|
69 |
+
.scrapy
|
70 |
+
|
71 |
+
# Sphinx documentation
|
72 |
+
docs/_build/
|
73 |
+
|
74 |
+
# PyBuilder
|
75 |
+
target/
|
76 |
+
|
77 |
+
# Jupyter Notebook
|
78 |
+
.ipynb_checkpoints
|
79 |
+
|
80 |
+
# IPython
|
81 |
+
profile_default/
|
82 |
+
ipython_config.py
|
83 |
+
|
84 |
+
# pyenv
|
85 |
+
.python-version
|
86 |
+
|
87 |
+
# pipenv
|
88 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
89 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
90 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
91 |
+
# install all needed dependencies.
|
92 |
+
#Pipfile.lock
|
93 |
+
|
94 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
95 |
+
__pypackages__/
|
96 |
+
|
97 |
+
# Celery stuff
|
98 |
+
celerybeat-schedule
|
99 |
+
celerybeat.pid
|
100 |
+
|
101 |
+
# SageMath parsed files
|
102 |
+
*.sage.py
|
103 |
+
|
104 |
+
# Environments
|
105 |
+
.env
|
106 |
+
.venv
|
107 |
+
env/
|
108 |
+
venv/
|
109 |
+
ENV/
|
110 |
+
env.bak/
|
111 |
+
venv.bak/
|
112 |
+
|
113 |
+
# Spyder project settings
|
114 |
+
.spyderproject
|
115 |
+
.spyproject
|
116 |
+
|
117 |
+
# Rope project settings
|
118 |
+
.ropeproject
|
119 |
+
|
120 |
+
# mkdocs documentation
|
121 |
+
/site
|
122 |
+
|
123 |
+
# mypy
|
124 |
+
.mypy_cache/
|
125 |
+
.dmypy.json
|
126 |
+
dmypy.json
|
127 |
+
|
128 |
+
# Pyre type checker
|
129 |
+
.pyre/
|
third_party/mast3r/.gitmodules
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[submodule "dust3r"]
|
2 |
+
path = dust3r
|
3 |
+
url = https://github.com/naver/dust3r
|
4 |
+
branch = cvpr
|
third_party/mast3r/CHECKPOINTS_NOTICE
ADDED
@@ -0,0 +1,1376 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
MASt3R
|
2 |
+
Copyright 2024-present NAVER Corp.
|
3 |
+
|
4 |
+
This project's checkpoints were trained on datasets with separate license terms.
|
5 |
+
Your use of theses checkpoints is subject to the terms and conditions of the following licenses.
|
6 |
+
|
7 |
+
===
|
8 |
+
pretrained model:
|
9 |
+
DUSt3R: DUSt3R_ViTLarge_BaseDecoder_512_dpt
|
10 |
+
https://github.com/naver/dust3r
|
11 |
+
|
12 |
+
In particular, from the croco training set:
|
13 |
+
|
14 |
+
3D_Street_View
|
15 |
+
https://github.com/amir32002/3D_Street_View/blob/master/LICENSE
|
16 |
+
This dataset is made freely available to academic and non-academic entities for non-commercial purposes such as academic research, teaching, scientific publications, or personal experimentation. Permission is granted to use the data given that you agree:
|
17 |
+
|
18 |
+
1. That the dataset comes "AS IS", without express or implied warranty. Although every effort has been made to ensure accuracy, we do not accept any responsibility for errors or omissions.
|
19 |
+
|
20 |
+
2. That you include a reference to the Dataset in any work that makes use of the dataset. For research papers, cite our publication as listed on our website.
|
21 |
+
|
22 |
+
3. That you do not distribute this dataset or modified versions. It is permissible to distribute derivative works in as far as they are abstract representations of this dataset (such as models trained on it or additional annotations that do not directly include any of our data) and do not allow to recover the dataset or something similar in character.
|
23 |
+
|
24 |
+
4. That you may not use the dataset or any derivative work for commercial purposes as, for example, licensing or selling the data, or using the data with a purpose to procure a commercial gain.
|
25 |
+
That all rights not expressly granted to you are reserved by us.
|
26 |
+
|
27 |
+
In addition, using the dataset is subject to the following standard terms:
|
28 |
+
|
29 |
+
|
30 |
+
Apache License
|
31 |
+
Version 2.0, January 2004
|
32 |
+
http://www.apache.org/licenses/
|
33 |
+
|
34 |
+
Indoor Visual Localization datasets (IndoorVL)
|
35 |
+
https://challenge.naverlabs.com/kapture/GangnamStation_LICENSE.txt
|
36 |
+
https://challenge.naverlabs.com/kapture/HyundaiDepartmentStore_LICENSE.txt
|
37 |
+
|
38 |
+
LICENSE.txt
|
39 |
+
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 (modified ver.)
|
40 |
+
International Public License
|
41 |
+
|
42 |
+
By exercising the Licensed Rights (defined below), You accept and agree
|
43 |
+
to be bound by the terms and conditions of this Creative Commons
|
44 |
+
Attribution-NonCommercial-NoDerivatives 4.0 International Public
|
45 |
+
License ("Public License"). To the extent this Public License may be
|
46 |
+
interpreted as a contract, You are granted the Licensed Rights in
|
47 |
+
consideration of Your acceptance of these terms and conditions, and the
|
48 |
+
Licensor grants You such rights in consideration of benefits the
|
49 |
+
Licensor receives from making the Licensed Material available under
|
50 |
+
these terms and conditions.
|
51 |
+
|
52 |
+
|
53 |
+
Section 1 -- Definitions.
|
54 |
+
|
55 |
+
a. Adapted Material means material subject to Copyright and Similar
|
56 |
+
Rights that is derived from or based upon the Licensed Material
|
57 |
+
and in which the Licensed Material is translated, altered,
|
58 |
+
arranged, transformed, or otherwise modified in a manner requiring
|
59 |
+
permission under the Copyright and Similar Rights held by the
|
60 |
+
Licensor. For purposes of this Public License, where the Licensed
|
61 |
+
Material is a musical work, performance, or sound recording,
|
62 |
+
Adapted Material is always produced where the Licensed Material is
|
63 |
+
synched in timed relation with a moving image.
|
64 |
+
|
65 |
+
b. Copyright and Similar Rights means copyright and/or similar rights
|
66 |
+
closely related to copyright including, without limitation,
|
67 |
+
performance, broadcast, sound recording, and Sui Generis Database
|
68 |
+
Rights, without regard to how the rights are labeled or
|
69 |
+
categorized. For purposes of this Public License, the rights
|
70 |
+
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
71 |
+
Rights.
|
72 |
+
|
73 |
+
c. Effective Technological Measures means those measures that, in the
|
74 |
+
absence of proper authority, may not be circumvented under laws
|
75 |
+
fulfilling obligations under Article 11 of the WIPO Copyright
|
76 |
+
Treaty adopted on December 20, 1996, and/or similar international
|
77 |
+
agreements.
|
78 |
+
|
79 |
+
d. Exceptions and Limitations means fair use, fair dealing, and/or
|
80 |
+
any other exception or limitation to Copyright and Similar Rights
|
81 |
+
that applies to Your use of the Licensed Material.
|
82 |
+
|
83 |
+
e. Licensed Material means the artistic or literary work, database,
|
84 |
+
or other material to which the Licensor applied this Public
|
85 |
+
License.
|
86 |
+
|
87 |
+
f. Licensed Rights means the rights granted to You subject to the
|
88 |
+
terms and conditions of this Public License, which are limited to
|
89 |
+
all Copyright and Similar Rights that apply to Your use of the
|
90 |
+
Licensed Material and that the Licensor has authority to license.
|
91 |
+
|
92 |
+
g. Licensor means the individual(s) or entity(ies) granting rights
|
93 |
+
under this Public License.
|
94 |
+
|
95 |
+
h. NonCommercial means not primarily intended for or directed towards
|
96 |
+
commercial advantage or monetary compensation. For purposes of
|
97 |
+
this Public License, the exchange of the Licensed Material for
|
98 |
+
other material subject to Copyright and Similar Rights by digital
|
99 |
+
file-sharing or similar means is NonCommercial provided there is
|
100 |
+
no payment of monetary compensation in connection with the
|
101 |
+
exchange.
|
102 |
+
|
103 |
+
i. Share means to provide material to the public by any means or
|
104 |
+
process that requires permission under the Licensed Rights, such
|
105 |
+
as reproduction, public display, public performance, distribution,
|
106 |
+
dissemination, communication, or importation, and to make material
|
107 |
+
available to the public including in ways that members of the
|
108 |
+
public may access the material from a place and at a time
|
109 |
+
individually chosen by them.
|
110 |
+
|
111 |
+
j. Sui Generis Database Rights means rights other than copyright
|
112 |
+
resulting from Directive 96/9/EC of the European Parliament and of
|
113 |
+
the Council of 11 March 1996 on the legal protection of databases,
|
114 |
+
as amended and/or succeeded, as well as other essentially
|
115 |
+
equivalent rights anywhere in the world.
|
116 |
+
|
117 |
+
k. You means the individual or entity exercising the Licensed Rights
|
118 |
+
under this Public License. Your has a corresponding meaning.
|
119 |
+
|
120 |
+
l. Research purpose means to publish research achievements in a research paper
|
121 |
+
|
122 |
+
|
123 |
+
Section 2 -- Scope.
|
124 |
+
|
125 |
+
a. License grant.
|
126 |
+
|
127 |
+
1. Subject to the terms and conditions of this Public License,
|
128 |
+
the Licensor hereby grants You a worldwide, royalty-free,
|
129 |
+
non-sublicensable, non-exclusive, irrevocable license to
|
130 |
+
exercise the Licensed Rights in the Licensed Material to:
|
131 |
+
|
132 |
+
a. reproduce and Share the Licensed Material, in whole or
|
133 |
+
in part, for NonCommercial purposes only; and
|
134 |
+
|
135 |
+
b. produce and reproduce, but not Share, Adapted Material
|
136 |
+
for NonCommercial purposes only.
|
137 |
+
|
138 |
+
c. reproduce and share the Adapted Matrerial, in part,
|
139 |
+
for Research purposes only.
|
140 |
+
|
141 |
+
2. Exceptions and Limitations. For the avoidance of doubt, where
|
142 |
+
Exceptions and Limitations apply to Your use, this Public
|
143 |
+
License does not apply, and You do not need to comply with
|
144 |
+
its terms and conditions.
|
145 |
+
|
146 |
+
3. Term. The term of this Public License is specified in Section
|
147 |
+
6(a).
|
148 |
+
|
149 |
+
4. Media and formats; technical modifications allowed. The
|
150 |
+
Licensor authorizes You to exercise the Licensed Rights in
|
151 |
+
all media and formats whether now known or hereafter created,
|
152 |
+
and to make technical modifications necessary to do so. The
|
153 |
+
Licensor waives and/or agrees not to assert any right or
|
154 |
+
authority to forbid You from making technical modifications
|
155 |
+
necessary to exercise the Licensed Rights, including
|
156 |
+
technical modifications necessary to circumvent Effective
|
157 |
+
Technological Measures. For purposes of this Public License,
|
158 |
+
simply making modifications authorized by this Section 2(a)
|
159 |
+
(4) never produces Adapted Material.
|
160 |
+
|
161 |
+
5. Downstream recipients.
|
162 |
+
|
163 |
+
a. Offer from the Licensor -- Licensed Material. Every
|
164 |
+
recipient of the Licensed Material automatically
|
165 |
+
receives an offer from the Licensor to exercise the
|
166 |
+
Licensed Rights under the terms and conditions of this
|
167 |
+
Public License.
|
168 |
+
|
169 |
+
b. No downstream restrictions. You may not offer or impose
|
170 |
+
any additional or different terms or conditions on, or
|
171 |
+
apply any Effective Technological Measures to, the
|
172 |
+
Licensed Material if doing so restricts exercise of the
|
173 |
+
Licensed Rights by any recipient of the Licensed
|
174 |
+
Material.
|
175 |
+
|
176 |
+
6. No endorsement. Nothing in this Public License constitutes or
|
177 |
+
may be construed as permission to assert or imply that You
|
178 |
+
are, or that Your use of the Licensed Material is, connected
|
179 |
+
with, or sponsored, endorsed, or granted official status by,
|
180 |
+
the Licensor or others designated to receive attribution as
|
181 |
+
provided in Section 3(a)(1)(A)(i).
|
182 |
+
|
183 |
+
b. Other rights.
|
184 |
+
|
185 |
+
1. Moral rights, such as the right of integrity, are not
|
186 |
+
licensed under this Public License, nor are publicity,
|
187 |
+
privacy, and/or other similar personality rights; however, to
|
188 |
+
the extent possible, the Licensor waives and/or agrees not to
|
189 |
+
assert any such rights held by the Licensor to the limited
|
190 |
+
extent necessary to allow You to exercise the Licensed
|
191 |
+
Rights, but not otherwise.
|
192 |
+
|
193 |
+
2. Patent and trademark rights are not licensed under this
|
194 |
+
Public License.
|
195 |
+
|
196 |
+
3. To the extent possible, the Licensor waives any right to
|
197 |
+
collect royalties from You for the exercise of the Licensed
|
198 |
+
Rights, whether directly or through a collecting society
|
199 |
+
under any voluntary or waivable statutory or compulsory
|
200 |
+
licensing scheme. In all other cases the Licensor expressly
|
201 |
+
reserves any right to collect such royalties, including when
|
202 |
+
the Licensed Material is used other than for NonCommercial
|
203 |
+
purposes.
|
204 |
+
|
205 |
+
|
206 |
+
Section 3 -- License Conditions.
|
207 |
+
|
208 |
+
Your exercise of the Licensed Rights is expressly made subject to the
|
209 |
+
following conditions.
|
210 |
+
|
211 |
+
a. Attribution.
|
212 |
+
|
213 |
+
1. If You Share the Licensed Material(including in a research paper),
|
214 |
+
You must:
|
215 |
+
|
216 |
+
a. retain the following if it is supplied by the Licensor
|
217 |
+
with the Licensed Material:
|
218 |
+
|
219 |
+
i. identification of the creator(s) of the Licensed
|
220 |
+
Material and any others designated to receive
|
221 |
+
attribution, in any reasonable manner requested by
|
222 |
+
the Licensor (including by pseudonym if
|
223 |
+
designated);
|
224 |
+
|
225 |
+
ii. a copyright notice;
|
226 |
+
|
227 |
+
iii. a notice that refers to this Public License;
|
228 |
+
|
229 |
+
iv. a notice that refers to the disclaimer of
|
230 |
+
warranties;
|
231 |
+
|
232 |
+
v. a URI or hyperlink to the Licensed Material to the
|
233 |
+
extent reasonably practicable;
|
234 |
+
|
235 |
+
b. indicate if You modified the Licensed Material and
|
236 |
+
retain an indication of any previous modifications; and
|
237 |
+
|
238 |
+
c. indicate the Licensed Material is licensed under this
|
239 |
+
Public License, and include the text of, or the URI or
|
240 |
+
hyperlink to, this Public License.
|
241 |
+
|
242 |
+
For the avoidance of doubt, You do not have permission under
|
243 |
+
this Public License to Share Adapted Material.
|
244 |
+
|
245 |
+
2. You may satisfy the conditions in Section 3(a)(1) in any
|
246 |
+
reasonable manner based on the medium, means, and context in
|
247 |
+
which You Share the Licensed Material. For example, it may be
|
248 |
+
reasonable to satisfy the conditions by providing a URI or
|
249 |
+
hyperlink to a resource that includes the required
|
250 |
+
information.
|
251 |
+
|
252 |
+
3. If requested by the Licensor, You must remove any of the
|
253 |
+
information required by Section 3(a)(1)(A) to the extent
|
254 |
+
reasonably practicable.
|
255 |
+
|
256 |
+
|
257 |
+
Section 4 -- Sui Generis Database Rights.
|
258 |
+
|
259 |
+
Where the Licensed Rights include Sui Generis Database Rights that
|
260 |
+
apply to Your use of the Licensed Material:
|
261 |
+
|
262 |
+
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
263 |
+
to extract, reuse, reproduce, and Share all or a substantial
|
264 |
+
portion of the contents of the database for NonCommercial purposes
|
265 |
+
only and provided You do not Share Adapted Material;
|
266 |
+
|
267 |
+
b. if You include all or a substantial portion of the database
|
268 |
+
contents in a database in which You have Sui Generis Database
|
269 |
+
Rights, then the database in which You have Sui Generis Database
|
270 |
+
Rights (but not its individual contents) is Adapted Material; and
|
271 |
+
|
272 |
+
c. You must comply with the conditions in Section 3(a) if You Share
|
273 |
+
all or a substantial portion of the contents of the database.
|
274 |
+
|
275 |
+
For the avoidance of doubt, this Section 4 supplements and does not
|
276 |
+
replace Your obligations under this Public License where the Licensed
|
277 |
+
Rights include other Copyright and Similar Rights.
|
278 |
+
|
279 |
+
|
280 |
+
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
281 |
+
|
282 |
+
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
283 |
+
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
284 |
+
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
285 |
+
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
286 |
+
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
287 |
+
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
288 |
+
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
289 |
+
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
290 |
+
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
291 |
+
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
292 |
+
|
293 |
+
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
294 |
+
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
295 |
+
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
296 |
+
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
297 |
+
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
298 |
+
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
299 |
+
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
300 |
+
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
301 |
+
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
302 |
+
|
303 |
+
c. The disclaimer of warranties and limitation of liability provided
|
304 |
+
above shall be interpreted in a manner that, to the extent
|
305 |
+
possible, most closely approximates an absolute disclaimer and
|
306 |
+
waiver of all liability.
|
307 |
+
|
308 |
+
|
309 |
+
Section 6 -- Term and Termination.
|
310 |
+
|
311 |
+
a. This Public License applies for the term of the Copyright and
|
312 |
+
Similar Rights licensed here. However, if You fail to comply with
|
313 |
+
this Public License, then Your rights under this Public License
|
314 |
+
terminate automatically.
|
315 |
+
|
316 |
+
b. Where Your right to use the Licensed Material has terminated under
|
317 |
+
Section 6(a), it reinstates:
|
318 |
+
|
319 |
+
1. automatically as of the date the violation is cured, provided
|
320 |
+
it is cured within 30 days of Your discovery of the
|
321 |
+
violation; or
|
322 |
+
|
323 |
+
2. upon express reinstatement by the Licensor.
|
324 |
+
|
325 |
+
For the avoidance of doubt, this Section 6(b) does not affect any
|
326 |
+
right the Licensor may have to seek remedies for Your violations
|
327 |
+
of this Public License.
|
328 |
+
|
329 |
+
c. For the avoidance of doubt, the Licensor may also offer the
|
330 |
+
Licensed Material under separate terms or conditions or stop
|
331 |
+
distributing the Licensed Material at any time; however, doing so
|
332 |
+
will not terminate this Public License.
|
333 |
+
|
334 |
+
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
335 |
+
License.
|
336 |
+
|
337 |
+
|
338 |
+
Section 7 -- Other Terms and Conditions.
|
339 |
+
|
340 |
+
a. The Licensor shall not be bound by any additional or different
|
341 |
+
terms or conditions communicated by You unless expressly agreed.
|
342 |
+
|
343 |
+
b. Any arrangements, understandings, or agreements regarding the
|
344 |
+
Licensed Material not stated herein are separate from and
|
345 |
+
independent of the terms and conditions of this Public License.
|
346 |
+
|
347 |
+
|
348 |
+
Section 8 -- Interpretation.
|
349 |
+
|
350 |
+
a. For the avoidance of doubt, this Public License does not, and
|
351 |
+
shall not be interpreted to, reduce, limit, restrict, or impose
|
352 |
+
conditions on any use of the Licensed Material that could lawfully
|
353 |
+
be made without permission under this Public License.
|
354 |
+
|
355 |
+
b. To the extent possible, if any provision of this Public License is
|
356 |
+
deemed unenforceable, it shall be automatically reformed to the
|
357 |
+
minimum extent necessary to make it enforceable. If the provision
|
358 |
+
cannot be reformed, it shall be severed from this Public License
|
359 |
+
without affecting the enforceability of the remaining terms and
|
360 |
+
conditions.
|
361 |
+
|
362 |
+
c. No term or condition of this Public License will be waived and no
|
363 |
+
failure to comply consented to unless expressly agreed to by the
|
364 |
+
Licensor.
|
365 |
+
|
366 |
+
d. Nothing in this Public License constitutes or may be interpreted
|
367 |
+
as a limitation upon, or waiver of, any privileges and immunities
|
368 |
+
that apply to the Licensor or You, including from the legal
|
369 |
+
processes of any jurisdiction or authority.
|
370 |
+
|
371 |
+
===
|
372 |
+
CO3Dv2
|
373 |
+
|
374 |
+
Creative Commons Attribution-NonCommercial 4.0 International Public
|
375 |
+
License
|
376 |
+
|
377 |
+
By exercising the Licensed Rights (defined below), You accept and agree
|
378 |
+
to be bound by the terms and conditions of this Creative Commons
|
379 |
+
Attribution-NonCommercial 4.0 International Public License ("Public
|
380 |
+
License"). To the extent this Public License may be interpreted as a
|
381 |
+
contract, You are granted the Licensed Rights in consideration of Your
|
382 |
+
acceptance of these terms and conditions, and the Licensor grants You
|
383 |
+
such rights in consideration of benefits the Licensor receives from
|
384 |
+
making the Licensed Material available under these terms and
|
385 |
+
conditions.
|
386 |
+
|
387 |
+
Section 1 -- Definitions.
|
388 |
+
|
389 |
+
a. Adapted Material means material subject to Copyright and Similar
|
390 |
+
Rights that is derived from or based upon the Licensed Material
|
391 |
+
and in which the Licensed Material is translated, altered,
|
392 |
+
arranged, transformed, or otherwise modified in a manner requiring
|
393 |
+
permission under the Copyright and Similar Rights held by the
|
394 |
+
Licensor. For purposes of this Public License, where the Licensed
|
395 |
+
Material is a musical work, performance, or sound recording,
|
396 |
+
Adapted Material is always produced where the Licensed Material is
|
397 |
+
synched in timed relation with a moving image.
|
398 |
+
|
399 |
+
b. Adapter's License means the license You apply to Your Copyright
|
400 |
+
and Similar Rights in Your contributions to Adapted Material in
|
401 |
+
accordance with the terms and conditions of this Public License.
|
402 |
+
|
403 |
+
c. Copyright and Similar Rights means copyright and/or similar rights
|
404 |
+
closely related to copyright including, without limitation,
|
405 |
+
performance, broadcast, sound recording, and Sui Generis Database
|
406 |
+
Rights, without regard to how the rights are labeled or
|
407 |
+
categorized. For purposes of this Public License, the rights
|
408 |
+
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
409 |
+
Rights.
|
410 |
+
d. Effective Technological Measures means those measures that, in the
|
411 |
+
absence of proper authority, may not be circumvented under laws
|
412 |
+
fulfilling obligations under Article 11 of the WIPO Copyright
|
413 |
+
Treaty adopted on December 20, 1996, and/or similar international
|
414 |
+
agreements.
|
415 |
+
|
416 |
+
e. Exceptions and Limitations means fair use, fair dealing, and/or
|
417 |
+
any other exception or limitation to Copyright and Similar Rights
|
418 |
+
that applies to Your use of the Licensed Material.
|
419 |
+
|
420 |
+
f. Licensed Material means the artistic or literary work, database,
|
421 |
+
or other material to which the Licensor applied this Public
|
422 |
+
License.
|
423 |
+
|
424 |
+
g. Licensed Rights means the rights granted to You subject to the
|
425 |
+
terms and conditions of this Public License, which are limited to
|
426 |
+
all Copyright and Similar Rights that apply to Your use of the
|
427 |
+
Licensed Material and that the Licensor has authority to license.
|
428 |
+
|
429 |
+
h. Licensor means the individual(s) or entity(ies) granting rights
|
430 |
+
under this Public License.
|
431 |
+
|
432 |
+
i. NonCommercial means not primarily intended for or directed towards
|
433 |
+
commercial advantage or monetary compensation. For purposes of
|
434 |
+
this Public License, the exchange of the Licensed Material for
|
435 |
+
other material subject to Copyright and Similar Rights by digital
|
436 |
+
file-sharing or similar means is NonCommercial provided there is
|
437 |
+
no payment of monetary compensation in connection with the
|
438 |
+
exchange.
|
439 |
+
|
440 |
+
j. Share means to provide material to the public by any means or
|
441 |
+
process that requires permission under the Licensed Rights, such
|
442 |
+
as reproduction, public display, public performance, distribution,
|
443 |
+
dissemination, communication, or importation, and to make material
|
444 |
+
available to the public including in ways that members of the
|
445 |
+
public may access the material from a place and at a time
|
446 |
+
individually chosen by them.
|
447 |
+
|
448 |
+
k. Sui Generis Database Rights means rights other than copyright
|
449 |
+
resulting from Directive 96/9/EC of the European Parliament and of
|
450 |
+
the Council of 11 March 1996 on the legal protection of databases,
|
451 |
+
as amended and/or succeeded, as well as other essentially
|
452 |
+
equivalent rights anywhere in the world.
|
453 |
+
|
454 |
+
l. You means the individual or entity exercising the Licensed Rights
|
455 |
+
under this Public License. Your has a corresponding meaning.
|
456 |
+
|
457 |
+
Section 2 -- Scope.
|
458 |
+
|
459 |
+
a. License grant.
|
460 |
+
|
461 |
+
1. Subject to the terms and conditions of this Public License,
|
462 |
+
the Licensor hereby grants You a worldwide, royalty-free,
|
463 |
+
non-sublicensable, non-exclusive, irrevocable license to
|
464 |
+
exercise the Licensed Rights in the Licensed Material to:
|
465 |
+
|
466 |
+
a. reproduce and Share the Licensed Material, in whole or
|
467 |
+
in part, for NonCommercial purposes only; and
|
468 |
+
|
469 |
+
b. produce, reproduce, and Share Adapted Material for
|
470 |
+
NonCommercial purposes only.
|
471 |
+
|
472 |
+
2. Exceptions and Limitations. For the avoidance of doubt, where
|
473 |
+
Exceptions and Limitations apply to Your use, this Public
|
474 |
+
License does not apply, and You do not need to comply with
|
475 |
+
its terms and conditions.
|
476 |
+
|
477 |
+
3. Term. The term of this Public License is specified in Section
|
478 |
+
6(a).
|
479 |
+
|
480 |
+
4. Media and formats; technical modifications allowed. The
|
481 |
+
Licensor authorizes You to exercise the Licensed Rights in
|
482 |
+
all media and formats whether now known or hereafter created,
|
483 |
+
and to make technical modifications necessary to do so. The
|
484 |
+
Licensor waives and/or agrees not to assert any right or
|
485 |
+
authority to forbid You from making technical modifications
|
486 |
+
necessary to exercise the Licensed Rights, including
|
487 |
+
technical modifications necessary to circumvent Effective
|
488 |
+
Technological Measures. For purposes of this Public License,
|
489 |
+
simply making modifications authorized by this Section 2(a)
|
490 |
+
(4) never produces Adapted Material.
|
491 |
+
|
492 |
+
5. Downstream recipients.
|
493 |
+
|
494 |
+
a. Offer from the Licensor -- Licensed Material. Every
|
495 |
+
recipient of the Licensed Material automatically
|
496 |
+
receives an offer from the Licensor to exercise the
|
497 |
+
Licensed Rights under the terms and conditions of this
|
498 |
+
Public License.
|
499 |
+
|
500 |
+
b. No downstream restrictions. You may not offer or impose
|
501 |
+
any additional or different terms or conditions on, or
|
502 |
+
apply any Effective Technological Measures to, the
|
503 |
+
Licensed Material if doing so restricts exercise of the
|
504 |
+
Licensed Rights by any recipient of the Licensed
|
505 |
+
Material.
|
506 |
+
|
507 |
+
6. No endorsement. Nothing in this Public License constitutes or
|
508 |
+
may be construed as permission to assert or imply that You
|
509 |
+
are, or that Your use of the Licensed Material is, connected
|
510 |
+
with, or sponsored, endorsed, or granted official status by,
|
511 |
+
the Licensor or others designated to receive attribution as
|
512 |
+
provided in Section 3(a)(1)(A)(i).
|
513 |
+
|
514 |
+
b. Other rights.
|
515 |
+
|
516 |
+
1. Moral rights, such as the right of integrity, are not
|
517 |
+
licensed under this Public License, nor are publicity,
|
518 |
+
privacy, and/or other similar personality rights; however, to
|
519 |
+
the extent possible, the Licensor waives and/or agrees not to
|
520 |
+
assert any such rights held by the Licensor to the limited
|
521 |
+
extent necessary to allow You to exercise the Licensed
|
522 |
+
Rights, but not otherwise.
|
523 |
+
|
524 |
+
2. Patent and trademark rights are not licensed under this
|
525 |
+
Public License.
|
526 |
+
|
527 |
+
3. To the extent possible, the Licensor waives any right to
|
528 |
+
collect royalties from You for the exercise of the Licensed
|
529 |
+
Rights, whether directly or through a collecting society
|
530 |
+
under any voluntary or waivable statutory or compulsory
|
531 |
+
licensing scheme. In all other cases the Licensor expressly
|
532 |
+
reserves any right to collect such royalties, including when
|
533 |
+
the Licensed Material is used other than for NonCommercial
|
534 |
+
purposes.
|
535 |
+
|
536 |
+
Section 3 -- License Conditions.
|
537 |
+
|
538 |
+
Your exercise of the Licensed Rights is expressly made subject to the
|
539 |
+
following conditions.
|
540 |
+
|
541 |
+
a. Attribution.
|
542 |
+
|
543 |
+
1. If You Share the Licensed Material (including in modified
|
544 |
+
form), You must:
|
545 |
+
|
546 |
+
a. retain the following if it is supplied by the Licensor
|
547 |
+
with the Licensed Material:
|
548 |
+
|
549 |
+
i. identification of the creator(s) of the Licensed
|
550 |
+
Material and any others designated to receive
|
551 |
+
attribution, in any reasonable manner requested by
|
552 |
+
the Licensor (including by pseudonym if
|
553 |
+
designated);
|
554 |
+
|
555 |
+
ii. a copyright notice;
|
556 |
+
|
557 |
+
iii. a notice that refers to this Public License;
|
558 |
+
|
559 |
+
iv. a notice that refers to the disclaimer of
|
560 |
+
warranties;
|
561 |
+
|
562 |
+
v. a URI or hyperlink to the Licensed Material to the
|
563 |
+
extent reasonably practicable;
|
564 |
+
|
565 |
+
b. indicate if You modified the Licensed Material and
|
566 |
+
retain an indication of any previous modifications; and
|
567 |
+
|
568 |
+
c. indicate the Licensed Material is licensed under this
|
569 |
+
Public License, and include the text of, or the URI or
|
570 |
+
hyperlink to, this Public License.
|
571 |
+
|
572 |
+
2. You may satisfy the conditions in Section 3(a)(1) in any
|
573 |
+
reasonable manner based on the medium, means, and context in
|
574 |
+
which You Share the Licensed Material. For example, it may be
|
575 |
+
reasonable to satisfy the conditions by providing a URI or
|
576 |
+
hyperlink to a resource that includes the required
|
577 |
+
information.
|
578 |
+
|
579 |
+
3. If requested by the Licensor, You must remove any of the
|
580 |
+
information required by Section 3(a)(1)(A) to the extent
|
581 |
+
reasonably practicable.
|
582 |
+
|
583 |
+
4. If You Share Adapted Material You produce, the Adapter's
|
584 |
+
License You apply must not prevent recipients of the Adapted
|
585 |
+
Material from complying with this Public License.
|
586 |
+
|
587 |
+
Section 4 -- Sui Generis Database Rights.
|
588 |
+
|
589 |
+
Where the Licensed Rights include Sui Generis Database Rights that
|
590 |
+
apply to Your use of the Licensed Material:
|
591 |
+
|
592 |
+
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
593 |
+
to extract, reuse, reproduce, and Share all or a substantial
|
594 |
+
portion of the contents of the database for NonCommercial purposes
|
595 |
+
only;
|
596 |
+
|
597 |
+
b. if You include all or a substantial portion of the database
|
598 |
+
contents in a database in which You have Sui Generis Database
|
599 |
+
Rights, then the database in which You have Sui Generis Database
|
600 |
+
Rights (but not its individual contents) is Adapted Material; and
|
601 |
+
|
602 |
+
c. You must comply with the conditions in Section 3(a) if You Share
|
603 |
+
all or a substantial portion of the contents of the database.
|
604 |
+
|
605 |
+
For the avoidance of doubt, this Section 4 supplements and does not
|
606 |
+
replace Your obligations under this Public License where the Licensed
|
607 |
+
Rights include other Copyright and Similar Rights.
|
608 |
+
|
609 |
+
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
610 |
+
|
611 |
+
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
612 |
+
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
613 |
+
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
614 |
+
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
615 |
+
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
616 |
+
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
617 |
+
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
618 |
+
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
619 |
+
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
620 |
+
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
621 |
+
|
622 |
+
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
623 |
+
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
624 |
+
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
625 |
+
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
626 |
+
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
627 |
+
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
628 |
+
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
629 |
+
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
630 |
+
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
631 |
+
|
632 |
+
c. The disclaimer of warranties and limitation of liability provided
|
633 |
+
above shall be interpreted in a manner that, to the extent
|
634 |
+
possible, most closely approximates an absolute disclaimer and
|
635 |
+
waiver of all liability.
|
636 |
+
|
637 |
+
Section 6 -- Term and Termination.
|
638 |
+
|
639 |
+
a. This Public License applies for the term of the Copyright and
|
640 |
+
Similar Rights licensed here. However, if You fail to comply with
|
641 |
+
this Public License, then Your rights under this Public License
|
642 |
+
terminate automatically.
|
643 |
+
|
644 |
+
b. Where Your right to use the Licensed Material has terminated under
|
645 |
+
Section 6(a), it reinstates:
|
646 |
+
|
647 |
+
1. automatically as of the date the violation is cured, provided
|
648 |
+
it is cured within 30 days of Your discovery of the
|
649 |
+
violation; or
|
650 |
+
|
651 |
+
2. upon express reinstatement by the Licensor.
|
652 |
+
|
653 |
+
For the avoidance of doubt, this Section 6(b) does not affect any
|
654 |
+
right the Licensor may have to seek remedies for Your violations
|
655 |
+
of this Public License.
|
656 |
+
|
657 |
+
c. For the avoidance of doubt, the Licensor may also offer the
|
658 |
+
Licensed Material under separate terms or conditions or stop
|
659 |
+
distributing the Licensed Material at any time; however, doing so
|
660 |
+
will not terminate this Public License.
|
661 |
+
|
662 |
+
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
663 |
+
License.
|
664 |
+
|
665 |
+
Section 7 -- Other Terms and Conditions.
|
666 |
+
|
667 |
+
a. The Licensor shall not be bound by any additional or different
|
668 |
+
terms or conditions communicated by You unless expressly agreed.
|
669 |
+
|
670 |
+
b. Any arrangements, understandings, or agreements regarding the
|
671 |
+
Licensed Material not stated herein are separate from and
|
672 |
+
independent of the terms and conditions of this Public License.
|
673 |
+
|
674 |
+
Section 8 -- Interpretation.
|
675 |
+
|
676 |
+
a. For the avoidance of doubt, this Public License does not, and
|
677 |
+
shall not be interpreted to, reduce, limit, restrict, or impose
|
678 |
+
conditions on any use of the Licensed Material that could lawfully
|
679 |
+
be made without permission under this Public License.
|
680 |
+
|
681 |
+
b. To the extent possible, if any provision of this Public License is
|
682 |
+
deemed unenforceable, it shall be automatically reformed to the
|
683 |
+
minimum extent necessary to make it enforceable. If the provision
|
684 |
+
cannot be reformed, it shall be severed from this Public License
|
685 |
+
without affecting the enforceability of the remaining terms and
|
686 |
+
conditions.
|
687 |
+
|
688 |
+
c. No term or condition of this Public License will be waived and no
|
689 |
+
failure to comply consented to unless expressly agreed to by the
|
690 |
+
Licensor.
|
691 |
+
|
692 |
+
d. Nothing in this Public License constitutes or may be interpreted
|
693 |
+
as a limitation upon, or waiver of, any privileges and immunities
|
694 |
+
that apply to the Licensor or You, including from the legal
|
695 |
+
processes of any jurisdiction or authority.
|
696 |
+
|
697 |
+
===
|
698 |
+
ARKitScenes
|
699 |
+
Creative Commons Attribution-NonCommercial-ShareAlike 4.0: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
700 |
+
|
701 |
+
===
|
702 |
+
ScanNet++
|
703 |
+
https://kaldir.vc.in.tum.de/scannetpp/static/scannetpp-terms-of-use.pdf
|
704 |
+
|
705 |
+
===
|
706 |
+
BlendedMVS
|
707 |
+
Creative Commons Attribution 4.0 International: http://creativecommons.org/licenses/by/4.0/
|
708 |
+
|
709 |
+
===
|
710 |
+
Habitat-Sim
|
711 |
+
HM3D
|
712 |
+
https://matterport.com/fr/legal/matterport-end-user-license-agreement-academic-use-model-data
|
713 |
+
|
714 |
+
ScanNet
|
715 |
+
https://kaldir.vc.in.tum.de/scannet/ScanNet_TOS.pdf
|
716 |
+
|
717 |
+
Replica
|
718 |
+
Before Facebook Technologies, LLC (“FB”) is able to offer you (“Researcher” or
|
719 |
+
“You”) access to the Replica Dataset (the “Dataset”), please read the following
|
720 |
+
agreement (“Agreement”).
|
721 |
+
|
722 |
+
By accessing, and in exchange for receiving permission to access, the Dataset,
|
723 |
+
Researcher hereby agrees to the following terms and conditions:
|
724 |
+
1. Researcher may use, modify, improve and/or publish the Dataset only in
|
725 |
+
connection with a research or educational purpose that is non-commercial or
|
726 |
+
not-for-profit in nature, and not for any other purpose.
|
727 |
+
1. Researcher may provide research associates and colleagues with access to the
|
728 |
+
Dataset provided that they first agree to be bound by these terms and
|
729 |
+
conditions.
|
730 |
+
1. Researcher may use the Dataset in the scope of their employment at a
|
731 |
+
for-profit or commercial entity provided that Researcher complies with Section 1
|
732 |
+
of this Agreement. If Researcher is employed by a for-profit or commercial
|
733 |
+
entity, Researcher's employer shall also be bound by these terms and conditions,
|
734 |
+
and Researcher hereby represents that they are fully authorized to enter into
|
735 |
+
this agreement on behalf of such employer.
|
736 |
+
1. THE DATASET IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
737 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
738 |
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL FB OR ANY
|
739 |
+
CONTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
740 |
+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
741 |
+
WITH THE DATASET OR THE USE OR OTHER DEALINGS IN THE DATASET.
|
742 |
+
1. The law of the State of California shall apply to all disputes related to
|
743 |
+
this Dataset.
|
744 |
+
|
745 |
+
ReplicaCAD
|
746 |
+
Creative Commons Attribution 4.0 International (CC BY 4.0): https://creativecommons.org/licenses/by/4.0/
|
747 |
+
|
748 |
+
habitat-sim
|
749 |
+
MIT License
|
750 |
+
|
751 |
+
Copyright (c) Meta Platforms, Inc. and its affiliates.
|
752 |
+
|
753 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
754 |
+
of this software and associated documentation files (the "Software"), to deal
|
755 |
+
in the Software without restriction, including without limitation the rights
|
756 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
757 |
+
copies of the Software, and to permit persons to whom the Software is
|
758 |
+
furnished to do so, subject to the following conditions:
|
759 |
+
|
760 |
+
The above copyright notice and this permission notice shall be included in all
|
761 |
+
copies or substantial portions of the Software.
|
762 |
+
|
763 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
764 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
765 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
766 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
767 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
768 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
769 |
+
SOFTWARE.
|
770 |
+
===
|
771 |
+
MegaDepth
|
772 |
+
MIT License
|
773 |
+
|
774 |
+
Copyright (c) 2018 Zhengqi Li
|
775 |
+
|
776 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
777 |
+
of this software and associated documentation files (the "Software"), to deal
|
778 |
+
in the Software without restriction, including without limitation the rights
|
779 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
780 |
+
copies of the Software, and to permit persons to whom the Software is
|
781 |
+
furnished to do so, subject to the following conditions:
|
782 |
+
|
783 |
+
The above copyright notice and this permission notice shall be included in all
|
784 |
+
copies or substantial portions of the Software.
|
785 |
+
|
786 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
787 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
788 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
789 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
790 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
791 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
792 |
+
SOFTWARE.
|
793 |
+
|
794 |
+
===
|
795 |
+
StaticThings3D
|
796 |
+
Apache License
|
797 |
+
Version 2.0, January 2004
|
798 |
+
http://www.apache.org/licenses/
|
799 |
+
|
800 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
801 |
+
|
802 |
+
1. Definitions.
|
803 |
+
|
804 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
805 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
806 |
+
|
807 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
808 |
+
the copyright owner that is granting the License.
|
809 |
+
|
810 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
811 |
+
other entities that control, are controlled by, or are under common
|
812 |
+
control with that entity. For the purposes of this definition,
|
813 |
+
"control" means (i) the power, direct or indirect, to cause the
|
814 |
+
direction or management of such entity, whether by contract or
|
815 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
816 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
817 |
+
|
818 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
819 |
+
exercising permissions granted by this License.
|
820 |
+
|
821 |
+
"Source" form shall mean the preferred form for making modifications,
|
822 |
+
including but not limited to software source code, documentation
|
823 |
+
source, and configuration files.
|
824 |
+
|
825 |
+
"Object" form shall mean any form resulting from mechanical
|
826 |
+
transformation or translation of a Source form, including but
|
827 |
+
not limited to compiled object code, generated documentation,
|
828 |
+
and conversions to other media types.
|
829 |
+
|
830 |
+
"Work" shall mean the work of authorship, whether in Source or
|
831 |
+
Object form, made available under the License, as indicated by a
|
832 |
+
copyright notice that is included in or attached to the work
|
833 |
+
(an example is provided in the Appendix below).
|
834 |
+
|
835 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
836 |
+
form, that is based on (or derived from) the Work and for which the
|
837 |
+
editorial revisions, annotations, elaborations, or other modifications
|
838 |
+
represent, as a whole, an original work of authorship. For the purposes
|
839 |
+
of this License, Derivative Works shall not include works that remain
|
840 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
841 |
+
the Work and Derivative Works thereof.
|
842 |
+
|
843 |
+
"Contribution" shall mean any work of authorship, including
|
844 |
+
the original version of the Work and any modifications or additions
|
845 |
+
to that Work or Derivative Works thereof, that is intentionally
|
846 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
847 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
848 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
849 |
+
means any form of electronic, verbal, or written communication sent
|
850 |
+
to the Licensor or its representatives, including but not limited to
|
851 |
+
communication on electronic mailing lists, source code control systems,
|
852 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
853 |
+
Licensor for the purpose of discussing and improving the Work, but
|
854 |
+
excluding communication that is conspicuously marked or otherwise
|
855 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
856 |
+
|
857 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
858 |
+
on behalf of whom a Contribution has been received by Licensor and
|
859 |
+
subsequently incorporated within the Work.
|
860 |
+
|
861 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
862 |
+
this License, each Contributor hereby grants to You a perpetual,
|
863 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
864 |
+
copyright license to reproduce, prepare Derivative Works of,
|
865 |
+
publicly display, publicly perform, sublicense, and distribute the
|
866 |
+
Work and such Derivative Works in Source or Object form.
|
867 |
+
|
868 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
869 |
+
this License, each Contributor hereby grants to You a perpetual,
|
870 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
871 |
+
(except as stated in this section) patent license to make, have made,
|
872 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
873 |
+
where such license applies only to those patent claims licensable
|
874 |
+
by such Contributor that are necessarily infringed by their
|
875 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
876 |
+
with the Work to which such Contribution(s) was submitted. If You
|
877 |
+
institute patent litigation against any entity (including a
|
878 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
879 |
+
or a Contribution incorporated within the Work constitutes direct
|
880 |
+
or contributory patent infringement, then any patent licenses
|
881 |
+
granted to You under this License for that Work shall terminate
|
882 |
+
as of the date such litigation is filed.
|
883 |
+
|
884 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
885 |
+
Work or Derivative Works thereof in any medium, with or without
|
886 |
+
modifications, and in Source or Object form, provided that You
|
887 |
+
meet the following conditions:
|
888 |
+
|
889 |
+
(a) You must give any other recipients of the Work or
|
890 |
+
Derivative Works a copy of this License; and
|
891 |
+
|
892 |
+
(b) You must cause any modified files to carry prominent notices
|
893 |
+
stating that You changed the files; and
|
894 |
+
|
895 |
+
(c) You must retain, in the Source form of any Derivative Works
|
896 |
+
that You distribute, all copyright, patent, trademark, and
|
897 |
+
attribution notices from the Source form of the Work,
|
898 |
+
excluding those notices that do not pertain to any part of
|
899 |
+
the Derivative Works; and
|
900 |
+
|
901 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
902 |
+
distribution, then any Derivative Works that You distribute must
|
903 |
+
include a readable copy of the attribution notices contained
|
904 |
+
within such NOTICE file, excluding those notices that do not
|
905 |
+
pertain to any part of the Derivative Works, in at least one
|
906 |
+
of the following places: within a NOTICE text file distributed
|
907 |
+
as part of the Derivative Works; within the Source form or
|
908 |
+
documentation, if provided along with the Derivative Works; or,
|
909 |
+
within a display generated by the Derivative Works, if and
|
910 |
+
wherever such third-party notices normally appear. The contents
|
911 |
+
of the NOTICE file are for informational purposes only and
|
912 |
+
do not modify the License. You may add Your own attribution
|
913 |
+
notices within Derivative Works that You distribute, alongside
|
914 |
+
or as an addendum to the NOTICE text from the Work, provided
|
915 |
+
that such additional attribution notices cannot be construed
|
916 |
+
as modifying the License.
|
917 |
+
|
918 |
+
You may add Your own copyright statement to Your modifications and
|
919 |
+
may provide additional or different license terms and conditions
|
920 |
+
for use, reproduction, or distribution of Your modifications, or
|
921 |
+
for any such Derivative Works as a whole, provided Your use,
|
922 |
+
reproduction, and distribution of the Work otherwise complies with
|
923 |
+
the conditions stated in this License.
|
924 |
+
|
925 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
926 |
+
any Contribution intentionally submitted for inclusion in the Work
|
927 |
+
by You to the Licensor shall be under the terms and conditions of
|
928 |
+
this License, without any additional terms or conditions.
|
929 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
930 |
+
the terms of any separate license agreement you may have executed
|
931 |
+
with Licensor regarding such Contributions.
|
932 |
+
|
933 |
+
6. Trademarks. This License does not grant permission to use the trade
|
934 |
+
names, trademarks, service marks, or product names of the Licensor,
|
935 |
+
except as required for reasonable and customary use in describing the
|
936 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
937 |
+
|
938 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
939 |
+
agreed to in writing, Licensor provides the Work (and each
|
940 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
941 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
942 |
+
implied, including, without limitation, any warranties or conditions
|
943 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
944 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
945 |
+
appropriateness of using or redistributing the Work and assume any
|
946 |
+
risks associated with Your exercise of permissions under this License.
|
947 |
+
|
948 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
949 |
+
whether in tort (including negligence), contract, or otherwise,
|
950 |
+
unless required by applicable law (such as deliberate and grossly
|
951 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
952 |
+
liable to You for damages, including any direct, indirect, special,
|
953 |
+
incidental, or consequential damages of any character arising as a
|
954 |
+
result of this License or out of the use or inability to use the
|
955 |
+
Work (including but not limited to damages for loss of goodwill,
|
956 |
+
work stoppage, computer failure or malfunction, or any and all
|
957 |
+
other commercial damages or losses), even if such Contributor
|
958 |
+
has been advised of the possibility of such damages.
|
959 |
+
|
960 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
961 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
962 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
963 |
+
or other liability obligations and/or rights consistent with this
|
964 |
+
License. However, in accepting such obligations, You may act only
|
965 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
966 |
+
of any other Contributor, and only if You agree to indemnify,
|
967 |
+
defend, and hold each Contributor harmless for any liability
|
968 |
+
incurred by, or claims asserted against, such Contributor by reason
|
969 |
+
of your accepting any such warranty or additional liability.
|
970 |
+
|
971 |
+
===
|
972 |
+
WildRGB-D
|
973 |
+
https://github.com/wildrgbd/wildrgbd/
|
974 |
+
MIT License
|
975 |
+
|
976 |
+
Copyright (c) 2024 rowdataset
|
977 |
+
|
978 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
979 |
+
of this software and associated documentation files (the "Software"), to deal
|
980 |
+
in the Software without restriction, including without limitation the rights
|
981 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
982 |
+
copies of the Software, and to permit persons to whom the Software is
|
983 |
+
furnished to do so, subject to the following conditions:
|
984 |
+
|
985 |
+
The above copyright notice and this permission notice shall be included in all
|
986 |
+
copies or substantial portions of the Software.
|
987 |
+
|
988 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
989 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
990 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
991 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
992 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
993 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
994 |
+
SOFTWARE.
|
995 |
+
|
996 |
+
===
|
997 |
+
TartanAir
|
998 |
+
Creative Commons Attribution 4.0 International License: http://creativecommons.org/licenses/by/4.0/
|
999 |
+
|
1000 |
+
===
|
1001 |
+
UnrealStereo4K
|
1002 |
+
https://github.com/fabiotosi92/SMD-Nets
|
1003 |
+
MIT License
|
1004 |
+
|
1005 |
+
Copyright (c) 2021 Fabio Tosi
|
1006 |
+
|
1007 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
1008 |
+
of this software and associated documentation files (the "Software"), to deal
|
1009 |
+
in the Software without restriction, including without limitation the rights
|
1010 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
1011 |
+
copies of the Software, and to permit persons to whom the Software is
|
1012 |
+
furnished to do so, subject to the following conditions:
|
1013 |
+
|
1014 |
+
The above copyright notice and this permission notice shall be included in all
|
1015 |
+
copies or substantial portions of the Software.
|
1016 |
+
|
1017 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
1018 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
1019 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
1020 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
1021 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
1022 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
1023 |
+
SOFTWARE.
|
1024 |
+
|
1025 |
+
===
|
1026 |
+
Virtual KITTI 2
|
1027 |
+
Creative Commons Attribution-NonCommercial-ShareAlike 3.0: http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
|
1028 |
+
|
1029 |
+
===
|
1030 |
+
DL3DV
|
1031 |
+
DL3DV-10K Term of use and Creative Commons Attribution-NonCommercial 4.0 International License.
|
1032 |
+
|
1033 |
+
Terms of Use
|
1034 |
+
|
1035 |
+
Researcher shall use the Dataset only for non-commercial research and educational purposes.
|
1036 |
+
DL3DV-10K organization makes no representations or warranties regarding the dataset, including but not limited to warranties of non-infringement or fitness for a particular purpose.
|
1037 |
+
Researcher accepts full responsibility for his/her/their use of the Dataset and shall defend and indemnify DL3DV-10K organization, including its members, employees, Trustees, officers and agents, against any and all claims arising from Researcher's use of the Dataset, including but not limited to Researcher's use of any copies of copyrighted 3D models that he/she/they may create from the dataset.
|
1038 |
+
Researcher may provide research associates and colleagues with access to the Dataset, after receiving entity has also agreed to and signed these terms and conditions. Sharing the data otherwise is strictly prohibited.
|
1039 |
+
Following General Data Protection Regulation, Researcher must ensure that they can delete all person-specific data upon request.
|
1040 |
+
DL3DV-10K organization reserves the right to terminate Researcher's access to the Dataset at any time.
|
1041 |
+
If Researcher is employed by a for-profit, commercial entity, Researcher's employer shall also be bound by these terms and conditions, and Researcher hereby represents that he/she/they is/are fully authorized to enter into this agreement on behalf of such employer.
|
1042 |
+
The law of the Indiana State shall apply to all disputes under this agreement.
|
1043 |
+
|
1044 |
+
Creative Commons Attribution-NonCommercial 4.0 International Public License
|
1045 |
+
|
1046 |
+
By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
|
1047 |
+
|
1048 |
+
Section 1 -- Definitions.
|
1049 |
+
|
1050 |
+
a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
|
1051 |
+
|
1052 |
+
b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
|
1053 |
+
|
1054 |
+
c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
|
1055 |
+
|
1056 |
+
e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
|
1057 |
+
|
1058 |
+
f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
|
1059 |
+
|
1060 |
+
g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
|
1061 |
+
|
1062 |
+
h. Licensor means the individual(s) or entity(ies) granting rights under this Public License.
|
1063 |
+
|
1064 |
+
i. NonCommercial means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange.
|
1065 |
+
|
1066 |
+
j. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
|
1067 |
+
|
1068 |
+
k. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
|
1069 |
+
|
1070 |
+
l. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
|
1071 |
+
|
1072 |
+
Section 2 -- Scope.
|
1073 |
+
|
1074 |
+
a. License grant.
|
1075 |
+
|
1076 |
+
1. Subject to the terms and conditions of this Public License,
|
1077 |
+
the Licensor hereby grants You a worldwide, royalty-free,
|
1078 |
+
non-sublicensable, non-exclusive, irrevocable license to
|
1079 |
+
exercise the Licensed Rights in the Licensed Material to:
|
1080 |
+
|
1081 |
+
a. reproduce and Share the Licensed Material, in whole or
|
1082 |
+
in part, for NonCommercial purposes only; and
|
1083 |
+
|
1084 |
+
b. produce, reproduce, and Share Adapted Material for
|
1085 |
+
NonCommercial purposes only.
|
1086 |
+
|
1087 |
+
2. Exceptions and Limitations. For the avoidance of doubt, where
|
1088 |
+
Exceptions and Limitations apply to Your use, this Public
|
1089 |
+
License does not apply, and You do not need to comply with
|
1090 |
+
its terms and conditions.
|
1091 |
+
|
1092 |
+
3. Term. The term of this Public License is specified in Section
|
1093 |
+
6(a).
|
1094 |
+
|
1095 |
+
4. Media and formats; technical modifications allowed. The
|
1096 |
+
Licensor authorizes You to exercise the Licensed Rights in
|
1097 |
+
all media and formats whether now known or hereafter created,
|
1098 |
+
and to make technical modifications necessary to do so. The
|
1099 |
+
Licensor waives and/or agrees not to assert any right or
|
1100 |
+
authority to forbid You from making technical modifications
|
1101 |
+
necessary to exercise the Licensed Rights, including
|
1102 |
+
technical modifications necessary to circumvent Effective
|
1103 |
+
Technological Measures. For purposes of this Public License,
|
1104 |
+
simply making modifications authorized by this Section 2(a)
|
1105 |
+
(4) never produces Adapted Material.
|
1106 |
+
|
1107 |
+
5. Downstream recipients.
|
1108 |
+
|
1109 |
+
a. Offer from the Licensor -- Licensed Material. Every
|
1110 |
+
recipient of the Licensed Material automatically
|
1111 |
+
receives an offer from the Licensor to exercise the
|
1112 |
+
Licensed Rights under the terms and conditions of this
|
1113 |
+
Public License.
|
1114 |
+
|
1115 |
+
b. No downstream restrictions. You may not offer or impose
|
1116 |
+
any additional or different terms or conditions on, or
|
1117 |
+
apply any Effective Technological Measures to, the
|
1118 |
+
Licensed Material if doing so restricts exercise of the
|
1119 |
+
Licensed Rights by any recipient of the Licensed
|
1120 |
+
Material.
|
1121 |
+
|
1122 |
+
6. No endorsement. Nothing in this Public License constitutes or
|
1123 |
+
may be construed as permission to assert or imply that You
|
1124 |
+
are, or that Your use of the Licensed Material is, connected
|
1125 |
+
with, or sponsored, endorsed, or granted official status by,
|
1126 |
+
the Licensor or others designated to receive attribution as
|
1127 |
+
provided in Section 3(a)(1)(A)(i).
|
1128 |
+
|
1129 |
+
b. Other rights.
|
1130 |
+
|
1131 |
+
1. Moral rights, such as the right of integrity, are not
|
1132 |
+
licensed under this Public License, nor are publicity,
|
1133 |
+
privacy, and/or other similar personality rights; however, to
|
1134 |
+
the extent possible, the Licensor waives and/or agrees not to
|
1135 |
+
assert any such rights held by the Licensor to the limited
|
1136 |
+
extent necessary to allow You to exercise the Licensed
|
1137 |
+
Rights, but not otherwise.
|
1138 |
+
|
1139 |
+
2. Patent and trademark rights are not licensed under this
|
1140 |
+
Public License.
|
1141 |
+
|
1142 |
+
3. To the extent possible, the Licensor waives any right to
|
1143 |
+
collect royalties from You for the exercise of the Licensed
|
1144 |
+
Rights, whether directly or through a collecting society
|
1145 |
+
under any voluntary or waivable statutory or compulsory
|
1146 |
+
licensing scheme. In all other cases the Licensor expressly
|
1147 |
+
reserves any right to collect such royalties, including when
|
1148 |
+
the Licensed Material is used other than for NonCommercial
|
1149 |
+
purposes.
|
1150 |
+
|
1151 |
+
Section 3 -- License Conditions.
|
1152 |
+
|
1153 |
+
Your exercise of the Licensed Rights is expressly made subject to the following conditions.
|
1154 |
+
|
1155 |
+
a. Attribution.
|
1156 |
+
|
1157 |
+
1. If You Share the Licensed Material (including in modified
|
1158 |
+
form), You must:
|
1159 |
+
|
1160 |
+
a. retain the following if it is supplied by the Licensor
|
1161 |
+
with the Licensed Material:
|
1162 |
+
|
1163 |
+
i. identification of the creator(s) of the Licensed
|
1164 |
+
Material and any others designated to receive
|
1165 |
+
attribution, in any reasonable manner requested by
|
1166 |
+
the Licensor (including by pseudonym if
|
1167 |
+
designated);
|
1168 |
+
|
1169 |
+
ii. a copyright notice;
|
1170 |
+
|
1171 |
+
iii. a notice that refers to this Public License;
|
1172 |
+
|
1173 |
+
iv. a notice that refers to the disclaimer of
|
1174 |
+
warranties;
|
1175 |
+
|
1176 |
+
v. a URI or hyperlink to the Licensed Material to the
|
1177 |
+
extent reasonably practicable;
|
1178 |
+
|
1179 |
+
b. indicate if You modified the Licensed Material and
|
1180 |
+
retain an indication of any previous modifications; and
|
1181 |
+
|
1182 |
+
c. indicate the Licensed Material is licensed under this
|
1183 |
+
Public License, and include the text of, or the URI or
|
1184 |
+
hyperlink to, this Public License.
|
1185 |
+
|
1186 |
+
2. You may satisfy the conditions in Section 3(a)(1) in any
|
1187 |
+
reasonable manner based on the medium, means, and context in
|
1188 |
+
which You Share the Licensed Material. For example, it may be
|
1189 |
+
reasonable to satisfy the conditions by providing a URI or
|
1190 |
+
hyperlink to a resource that includes the required
|
1191 |
+
information.
|
1192 |
+
|
1193 |
+
3. If requested by the Licensor, You must remove any of the
|
1194 |
+
information required by Section 3(a)(1)(A) to the extent
|
1195 |
+
reasonably practicable.
|
1196 |
+
|
1197 |
+
4. If You Share Adapted Material You produce, the Adapter's
|
1198 |
+
License You apply must not prevent recipients of the Adapted
|
1199 |
+
Material from complying with this Public License.
|
1200 |
+
|
1201 |
+
Section 4 -- Sui Generis Database Rights.
|
1202 |
+
|
1203 |
+
Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
|
1204 |
+
|
1205 |
+
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only;
|
1206 |
+
|
1207 |
+
b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
|
1208 |
+
|
1209 |
+
c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
|
1210 |
+
|
1211 |
+
For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
|
1212 |
+
|
1213 |
+
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
1214 |
+
|
1215 |
+
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
1216 |
+
|
1217 |
+
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
1218 |
+
|
1219 |
+
c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
|
1220 |
+
|
1221 |
+
Section 6 -- Term and Termination.
|
1222 |
+
|
1223 |
+
a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
|
1224 |
+
|
1225 |
+
b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
|
1226 |
+
|
1227 |
+
1. automatically as of the date the violation is cured, provided
|
1228 |
+
it is cured within 30 days of Your discovery of the
|
1229 |
+
violation; or
|
1230 |
+
|
1231 |
+
2. upon express reinstatement by the Licensor.
|
1232 |
+
|
1233 |
+
For the avoidance of doubt, this Section 6(b) does not affect any
|
1234 |
+
right the Licensor may have to seek remedies for Your violations
|
1235 |
+
of this Public License.
|
1236 |
+
|
1237 |
+
c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
|
1238 |
+
|
1239 |
+
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
|
1240 |
+
|
1241 |
+
Section 7 -- Other Terms and Conditions.
|
1242 |
+
|
1243 |
+
a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
|
1244 |
+
|
1245 |
+
b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
|
1246 |
+
|
1247 |
+
Section 8 -- Interpretation.
|
1248 |
+
|
1249 |
+
a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
|
1250 |
+
|
1251 |
+
b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
|
1252 |
+
|
1253 |
+
c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
|
1254 |
+
|
1255 |
+
d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
|
1256 |
+
|
1257 |
+
===
|
1258 |
+
Niantic Map Free Relocalization Dataset License Agreement
|
1259 |
+
This Niantic Map Free Relocalization Dataset License Agreement ("Agreement") is an agreement between you and Niantic, Inc. (“Niantic” or “we”). By downloading or otherwise using Niantic’s Map-Free Relocalization dataset or dataset-derived materials (collectively, the "Dataset") you agree to:
|
1260 |
+
|
1261 |
+
1. Purpose and Restrictions. You may only use the Dataset only for non-commercial purposes, such as academic research at educational and not-for-profit research institutions, teaching, public demonstrations, and personal experimentation. Non-commercial use expressly excludes any profit-making or commercial activities, including without limitation sale, license, manufacture or development of commercial products, use in commercially-sponsored research, use at a laboratory or other facility owned or controlled (whether in whole or in part) by a commercial entity, provision of consulting service, use for or on behalf of any commercial entity, and use in consulting service, use for or on behalf of any commercial entity, use in research where a commercial party obtains rights to research results or any other benefit. Notwithstanding the foregoing restrictions, you can use this Dataset for publishing comparison results for academic papers, including retraining your models on this Dataset.
|
1262 |
+
|
1263 |
+
2. License. Subject to this Agreement, Niantic grants you a non-exclusive, non-transferable, non-sublicensable right to download and use the Dataset for the purpose stated in Section 1 of this Agreement. All rights not expressly granted to you in this Agreement are reserved.
|
1264 |
+
|
1265 |
+
3. Condition of Use. You must not use the Dataset in a way that could diminish, tarnish, or in any way harm Niantic’s reputation or image.
|
1266 |
+
|
1267 |
+
4. No Warranties. The Dataset comes “as is”, and you will use it at your own risk. Niantic makes no representations or warranties regarding the Dataset, including but not limited to warranties of non-infringement or fitness for a particular purpose. Neither Niantic nor any contributor to the Dataset will be liable for any damages related to the Dataset or this Agreement, including direct, indirect, special, consequential or incidental damages, to the maximum extent the law permits, no matter what legal theory they are based on. We are not obligated to (and will not) provide technical support for the Dataset.
|
1268 |
+
|
1269 |
+
5. Indemnity. You accept full responsibility for your use of the Dataset and shall defend and indemnify Niantic, including its employees, officers and agents, against any and all claims arising from your use of the Dataset.
|
1270 |
+
|
1271 |
+
6. Removal. Niantic reserves the right to remove access to the Dataset at any time without cause. If you have downloaded a copy of the Dataset prior to such removal, you may use such a copy subject to this Agreement, but you may not distribute your copy.
|
1272 |
+
|
1273 |
+
7. Termination. This Agreement will terminate immediately upon your commercial use of the Dataset.
|
1274 |
+
|
1275 |
+
8. Authorized Representative. If you are employed by a for-profit, commercial entity, your employer shall also be bound by the terms and conditions of this Agreement, and you hereby represent that you are fully authorized to enter into this Agreement on behalf of such employer.
|
1276 |
+
|
1277 |
+
9. Survivability. Sections 2, 4, 5, 6, 7, 8, 9, and 10 of this Agreement survive the termination of this Agreement.
|
1278 |
+
|
1279 |
+
10. Misc. This Agreement is governed and construed in all respects in accordance with the laws of the State of California, USA without regard to conflicts of law. If any provision of this Agreement is deemed unenforceable or contrary to law, the rest of this Agreement shall remain in full effect and enforceable. If you do not agree to this Agreement, do not download or use the Dataset. The Dataset is protected by copyright and other intellectual property laws and is licensed, not sold.
|
1280 |
+
|
1281 |
+
===
|
1282 |
+
NVIDIA Source Code License for SegFormer
|
1283 |
+
|
1284 |
+
1. Definitions
|
1285 |
+
|
1286 |
+
“Licensor” means any person or entity that distributes its Work.
|
1287 |
+
|
1288 |
+
“Software” means the original work of authorship made available under this License.
|
1289 |
+
|
1290 |
+
“Work” means the Software and any additions to or derivative works of the Software that are made available under
|
1291 |
+
this License.
|
1292 |
+
|
1293 |
+
The terms “reproduce,” “reproduction,” “derivative works,” and “distribution” have the meaning as provided under
|
1294 |
+
U.S. copyright law; provided, however, that for the purposes of this License, derivative works shall not include
|
1295 |
+
works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work.
|
1296 |
+
|
1297 |
+
Works, including the Software, are “made available” under this License by including in or with the Work either
|
1298 |
+
(a) a copyright notice referencing the applicability of this License to the Work, or (b) a copy of this License.
|
1299 |
+
|
1300 |
+
2. License Grant
|
1301 |
+
|
1302 |
+
2.1 Copyright Grant. Subject to the terms and conditions of this License, each Licensor grants to you a perpetual,
|
1303 |
+
worldwide, non-exclusive, royalty-free, copyright license to reproduce, prepare derivative works of, publicly
|
1304 |
+
display, publicly perform, sublicense and distribute its Work and any resulting derivative works in any form.
|
1305 |
+
|
1306 |
+
3. Limitations
|
1307 |
+
|
1308 |
+
3.1 Redistribution. You may reproduce or distribute the Work only if (a) you do so under this License, (b) you
|
1309 |
+
include a complete copy of this License with your distribution, and (c) you retain without modification any
|
1310 |
+
copyright, patent, trademark, or attribution notices that are present in the Work.
|
1311 |
+
|
1312 |
+
3.2 Derivative Works. You may specify that additional or different terms apply to the use, reproduction, and
|
1313 |
+
distribution of your derivative works of the Work (“Your Terms”) only if (a) Your Terms provide that the use
|
1314 |
+
limitation in Section 3.3 applies to your derivative works, and (b) you identify the specific derivative works
|
1315 |
+
that are subject to Your Terms. Notwithstanding Your Terms, this License (including the redistribution
|
1316 |
+
requirements in Section 3.1) will continue to apply to the Work itself.
|
1317 |
+
|
1318 |
+
3.3 Use Limitation. The Work and any derivative works thereof only may be used or intended for use
|
1319 |
+
non-commercially. Notwithstanding the foregoing, NVIDIA and its affiliates may use the Work and any derivative
|
1320 |
+
works commercially. As used herein, “non-commercially” means for research or evaluation purposes only.
|
1321 |
+
|
1322 |
+
3.4 Patent Claims. If you bring or threaten to bring a patent claim against any Licensor (including any claim,
|
1323 |
+
cross-claim or counterclaim in a lawsuit) to enforce any patents that you allege are infringed by any Work, then
|
1324 |
+
your rights under this License from such Licensor (including the grant in Section 2.1) will terminate immediately.
|
1325 |
+
|
1326 |
+
3.5 Trademarks. This License does not grant any rights to use any Licensor’s or its affiliates’ names, logos,
|
1327 |
+
or trademarks, except as necessary to reproduce the notices described in this License.
|
1328 |
+
|
1329 |
+
3.6 Termination. If you violate any term of this License, then your rights under this License (including the
|
1330 |
+
grant in Section 2.1) will terminate immediately.
|
1331 |
+
|
1332 |
+
4. Disclaimer of Warranty.
|
1333 |
+
|
1334 |
+
THE WORK IS PROVIDED “AS IS” WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
1335 |
+
WARRANTIES OR CONDITIONS OF M ERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT. YOU
|
1336 |
+
BEAR THE RISK OF UNDERTAKING ANY ACTIVITIES UNDER THIS LICENSE.
|
1337 |
+
|
1338 |
+
5. Limitation of Liability.
|
1339 |
+
|
1340 |
+
EXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL THEORY, WHETHER IN TORT (INCLUDING
|
1341 |
+
NEGLIGENCE), CONTRACT, OR OTHERWISE SHALL ANY LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT,
|
1342 |
+
INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATED TO THIS LICENSE, THE USE OR
|
1343 |
+
INABILITY TO USE THE WORK (INCLUDING BUT NOT LIMITED TO LOSS OF GOODWILL, BUSINESS INTERRUPTION, LOST PROFITS OR
|
1344 |
+
DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY OTHER COMM ERCIAL DAMAGES OR LOSSES), EVEN IF THE LICENSOR HAS BEEN
|
1345 |
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
1346 |
+
|
1347 |
+
===
|
1348 |
+
CosXL License Agreement
|
1349 |
+
|
1350 |
+
|
1351 |
+
STABILITY AI NON-COMMERCIAL RESEARCH COMMUNITY LICENSE AGREEMENT Dated: April 7th, 2024
|
1352 |
+
By clicking “I Accept” below or by using or distributing any portion or element of the Models, Software, Software Products or Derivative Works, you agree to the terms of this License. If you do not agree to this License, then you do not have any rights to use the Software Products or Derivative Works through this License, and you must immediately cease using the Software Products or Derivative Works. If you are agreeing to be bound by the terms of this License on behalf of your employer or other entity, you represent and warrant to Stability AI that you have full legal authority to bind your employer or such entity to this License. If you do not have the requisite authority, you may not accept the License or access the Software Products or Derivative Works on behalf of your employer or other entity.
|
1353 |
+
"Agreement" means this Stable Non-Commercial Research Community License Agreement.
|
1354 |
+
“AUP” means the Stability AI Acceptable Use Policy available at https://stability.ai/use-policy, as may be updated from time to time.
|
1355 |
+
"Derivative Work(s)” means (a) any derivative work of the Software Products as recognized by U.S. copyright laws and (b) any modifications to a Model, and any other model created which is based on or derived from the Model or the Model’s output. For clarity, Derivative Works do not include the output of any Model.
|
1356 |
+
“Documentation” means any specifications, manuals, documentation, and other written information provided by Stability AI related to the Software.
|
1357 |
+
"Licensee" or "you" means you, or your employer or any other person or entity (if you are entering into this Agreement on such person or entity's behalf), of the age required under applicable laws, rules or regulations to provide legal consent and that has legal authority to bind your employer or such other person or entity if you are entering in this Agreement on their behalf.
|
1358 |
+
“Model(s)" means, collectively, Stability AI’s proprietary models and algorithms, including machine-learning models, trained model weights and other elements of the foregoing, made available under this Agreement.
|
1359 |
+
“Non-Commercial Uses” means exercising any of the rights granted herein for the purpose of research or non-commercial purposes. Non-Commercial Uses does not include any production use of the Software Products or any Derivative Works.
|
1360 |
+
"Stability AI" or "we" means Stability AI Ltd. and its affiliates.
|
1361 |
+
|
1362 |
+
"Software" means Stability AI’s proprietary software made available under this Agreement.
|
1363 |
+
“Software Products” means the Models, Software and Documentation, individually or in any combination.
|
1364 |
+
|
1365 |
+
License Rights and Redistribution.
|
1366 |
+
a. Subject to your compliance with this Agreement, the AUP (which is hereby incorporated herein by reference), and the Documentation, Stability AI grants you a non-exclusive, worldwide, non-transferable, non-sublicensable, revocable, royalty free and limited license under Stability AI’s intellectual property or other rights owned or controlled by Stability AI embodied in the Software Products to use, reproduce, distribute, and create Derivative Works of, the Software Products, in each case for Non-Commercial Uses only.
|
1367 |
+
b. You may not use the Software Products or Derivative Works to enable third parties to use the Software Products or Derivative Works as part of your hosted service or via your APIs, whether you are adding substantial additional functionality thereto or not. Merely distributing the Software Products or Derivative Works for download online without offering any related service (ex. by distributing the Models on HuggingFace) is not a violation of this subsection. If you wish to use the Software Products or any Derivative Works for commercial or production use or you wish to make the Software Products or any Derivative Works available to third parties via your hosted service or your APIs, contact Stability AI at https://stability.ai/contact.
|
1368 |
+
c. If you distribute or make the Software Products, or any Derivative Works thereof, available to a third party, the Software Products, Derivative Works, or any portion thereof, respectively, will remain subject to this Agreement and you must (i) provide a copy of this Agreement to such third party, and (ii) retain the following attribution notice within a "Notice" text file distributed as a part of such copies: "This Stability AI Model is licensed under the Stability AI Non-Commercial Research Community License, Copyright (c) Stability AI Ltd. All Rights Reserved.” If you create a Derivative Work of a Software Product, you may add your own attribution notices to the Notice file included with the Software Product, provided that you clearly indicate which attributions apply to the Software Product and you must state in the NOTICE file that you changed the Software Product and how it was modified.
|
1369 |
+
Disclaimer of Warranty. UNLESS REQUIRED BY APPLICABLE LAW, THE SOFTWARE PRODUCTS AND ANY OUTPUT AND RESULTS THEREFROM ARE PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING OR REDISTRIBUTING THE SOFTWARE PRODUCTS, DERIVATIVE WORKS OR ANY OUTPUT OR RESULTS AND ASSUME ANY RISKS ASSOCIATED WITH YOUR USE OF THE SOFTWARE PRODUCTS, DERIVATIVE WORKS AND ANY OUTPUT AND RESULTS. 3. Limitation of Liability. IN NO EVENT WILL STABILITY AI OR ITS AFFILIATES BE LIABLE UNDER ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, TORT, NEGLIGENCE, PRODUCTS LIABILITY, OR OTHERWISE, ARISING OUT OF THIS AGREEMENT, FOR ANY LOST PROFITS OR ANY DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL, EXEMPLARY OR PUNITIVE DAMAGES, EVEN IF STABILITY AI OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF ANY OF THE FOREGOING. 4. Intellectual Property.
|
1370 |
+
a. No trademark licenses are granted under this Agreement, and in connection with the Software Products or Derivative Works, neither Stability AI nor Licensee may use any name or mark owned by or associated with the other or any of its affiliates, except as required for reasonable and customary use in describing and redistributing the Software Products or Derivative Works.
|
1371 |
+
b. Subject to Stability AI’s ownership of the Software Products and Derivative Works made by or for Stability AI, with respect to any Derivative Works that are made by you, as between you and Stability AI, you are and will be the owner of such Derivative Works
|
1372 |
+
c. If you institute litigation or other proceedings against Stability AI (including a cross-claim or counterclaim in a lawsuit) alleging that the Software Products, Derivative Works or associated outputs or results, or any portion of any of the foregoing, constitutes infringement of intellectual property or other rights owned or licensable by you, then any licenses granted to you under this Agreement shall terminate as of the date such litigation or claim is filed or instituted. You will indemnify and hold harmless Stability AI from and against any claim by any third party arising out of or related to your use or distribution of the Software Products or Derivative Works in violation of this Agreement.
|
1373 |
+
Term and Termination. The term of this Agreement will commence upon your acceptance of this Agreement or access to the Software Products and will continue in full force and effect until terminated in accordance with the terms and conditions herein. Stability AI may terminate this Agreement if you are in breach of any term or condition of this Agreement. Upon termination of this Agreement, you shall delete and cease use of any Software Products or Derivative Works. Sections 2-4 shall survive the termination of this Agreement.
|
1374 |
+
Governing Law. This Agreement will be governed by and construed in accordance with the laws of the United States and the State of California without regard to choice of law
|
1375 |
+
principles.
|
1376 |
+
|
third_party/mast3r/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
DUSt3R, Copyright (c) 2024-present Naver Corporation, is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 license.
|
2 |
+
|
3 |
+
A summary of the CC BY-NC-SA 4.0 license is located here:
|
4 |
+
https://creativecommons.org/licenses/by-nc-sa/4.0/
|
5 |
+
|
6 |
+
The CC BY-NC-SA 4.0 license is located here:
|
7 |
+
https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
|
third_party/mast3r/NOTICE
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
MASt3R
|
2 |
+
Copyright 2024-present NAVER Corp.
|
3 |
+
|
4 |
+
This project contains subcomponents with separate copyright notices and license terms.
|
5 |
+
Your use of the source code for these subcomponents is subject to the terms and conditions of the following licenses.
|
6 |
+
|
7 |
+
====
|
8 |
+
|
9 |
+
naver/dust3r
|
10 |
+
https://github.com/naver/dust3r/
|
11 |
+
|
12 |
+
Creative Commons Attribution-NonCommercial-ShareAlike 4.0
|
13 |
+
|
14 |
+
====
|
15 |
+
|
16 |
+
naver/croco
|
17 |
+
https://github.com/naver/croco/
|
18 |
+
|
19 |
+
Creative Commons Attribution-NonCommercial-ShareAlike 4.0
|
20 |
+
|
21 |
+
====
|
22 |
+
|
23 |
+
pytorch/pytorch
|
24 |
+
https://github.com/pytorch/pytorch
|
25 |
+
|
26 |
+
From PyTorch:
|
27 |
+
|
28 |
+
Copyright (c) 2016- Facebook, Inc (Adam Paszke)
|
29 |
+
Copyright (c) 2014- Facebook, Inc (Soumith Chintala)
|
30 |
+
Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert)
|
31 |
+
Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu)
|
32 |
+
Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu)
|
33 |
+
Copyright (c) 2011-2013 NYU (Clement Farabet)
|
34 |
+
Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, Iain Melvin, Jason Weston)
|
35 |
+
Copyright (c) 2006 Idiap Research Institute (Samy Bengio)
|
36 |
+
Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, Samy Bengio, Johnny Mariethoz)
|
37 |
+
|
38 |
+
From Caffe2:
|
39 |
+
|
40 |
+
Copyright (c) 2016-present, Facebook Inc. All rights reserved.
|
41 |
+
|
42 |
+
All contributions by Facebook:
|
43 |
+
Copyright (c) 2016 Facebook Inc.
|
44 |
+
|
45 |
+
All contributions by Google:
|
46 |
+
Copyright (c) 2015 Google Inc.
|
47 |
+
All rights reserved.
|
48 |
+
|
49 |
+
All contributions by Yangqing Jia:
|
50 |
+
Copyright (c) 2015 Yangqing Jia
|
51 |
+
All rights reserved.
|
52 |
+
|
53 |
+
All contributions by Kakao Brain:
|
54 |
+
Copyright 2019-2020 Kakao Brain
|
55 |
+
|
56 |
+
All contributions by Cruise LLC:
|
57 |
+
Copyright (c) 2022 Cruise LLC.
|
58 |
+
All rights reserved.
|
59 |
+
|
60 |
+
All contributions from Caffe:
|
61 |
+
Copyright(c) 2013, 2014, 2015, the respective contributors
|
62 |
+
All rights reserved.
|
63 |
+
|
64 |
+
All other contributions:
|
65 |
+
Copyright(c) 2015, 2016 the respective contributors
|
66 |
+
All rights reserved.
|
67 |
+
|
68 |
+
Caffe2 uses a copyright model similar to Caffe: each contributor holds
|
69 |
+
copyright over their contributions to Caffe2. The project versioning records
|
70 |
+
all such contribution and copyright details. If a contributor wants to further
|
71 |
+
mark their specific copyright on a particular contribution, they should
|
72 |
+
indicate their copyright solely in the commit message of the change when it is
|
73 |
+
committed.
|
74 |
+
|
75 |
+
All rights reserved.
|
76 |
+
|
77 |
+
Redistribution and use in source and binary forms, with or without
|
78 |
+
modification, are permitted provided that the following conditions are met:
|
79 |
+
|
80 |
+
1. Redistributions of source code must retain the above copyright
|
81 |
+
notice, this list of conditions and the following disclaimer.
|
82 |
+
|
83 |
+
2. Redistributions in binary form must reproduce the above copyright
|
84 |
+
notice, this list of conditions and the following disclaimer in the
|
85 |
+
documentation and/or other materials provided with the distribution.
|
86 |
+
|
87 |
+
3. Neither the names of Facebook, Deepmind Technologies, NYU, NEC Laboratories America
|
88 |
+
and IDIAP Research Institute nor the names of its contributors may be
|
89 |
+
used to endorse or promote products derived from this software without
|
90 |
+
specific prior written permission.
|
91 |
+
|
92 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
93 |
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
94 |
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
95 |
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
96 |
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
97 |
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
98 |
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
99 |
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
100 |
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
101 |
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
102 |
+
POSSIBILITY OF SUCH DAMAGE.
|
103 |
+
|
third_party/mast3r/README.md
ADDED
@@ -0,0 +1,316 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
![banner](assets/mast3r.jpg)
|
2 |
+
|
3 |
+
Official implementation of `Grounding Image Matching in 3D with MASt3R`
|
4 |
+
[[Project page](https://dust3r.europe.naverlabs.com/)], [[MASt3R arxiv](https://arxiv.org/abs/2406.09756)], [[DUSt3R arxiv](https://arxiv.org/abs/2312.14132)]
|
5 |
+
|
6 |
+
![Example of matching results obtained from MASt3R](assets/examples.jpg)
|
7 |
+
|
8 |
+
![High level overview of MASt3R's architecture](assets/mast3r_archi.jpg)
|
9 |
+
|
10 |
+
```bibtex
|
11 |
+
@misc{mast3r_arxiv24,
|
12 |
+
title={Grounding Image Matching in 3D with MASt3R},
|
13 |
+
author={Vincent Leroy and Yohann Cabon and Jerome Revaud},
|
14 |
+
year={2024},
|
15 |
+
eprint={2406.09756},
|
16 |
+
archivePrefix={arXiv},
|
17 |
+
primaryClass={cs.CV}
|
18 |
+
}
|
19 |
+
|
20 |
+
@inproceedings{dust3r_cvpr24,
|
21 |
+
title={DUSt3R: Geometric 3D Vision Made Easy},
|
22 |
+
author={Shuzhe Wang and Vincent Leroy and Yohann Cabon and Boris Chidlovskii and Jerome Revaud},
|
23 |
+
booktitle = {CVPR},
|
24 |
+
year = {2024}
|
25 |
+
}
|
26 |
+
```
|
27 |
+
|
28 |
+
## Table of Contents
|
29 |
+
|
30 |
+
- [Table of Contents](#table-of-contents)
|
31 |
+
- [License](#license)
|
32 |
+
- [Get Started](#get-started)
|
33 |
+
- [Installation](#installation)
|
34 |
+
- [Checkpoints](#checkpoints)
|
35 |
+
- [Interactive demo](#interactive-demo)
|
36 |
+
- [Interactive demo with docker](#interactive-demo-with-docker)
|
37 |
+
- [Usage](#usage)
|
38 |
+
- [Training](#training)
|
39 |
+
- [Datasets](#datasets)
|
40 |
+
- [Demo](#demo)
|
41 |
+
- [Our Hyperparameters](#our-hyperparameters)
|
42 |
+
- [Visual Localization](#visual-localization)
|
43 |
+
- [Dataset Preparation](#dataset-preparation)
|
44 |
+
- [Example Commands](#example-commands)
|
45 |
+
|
46 |
+
## License
|
47 |
+
|
48 |
+
The code is distributed under the CC BY-NC-SA 4.0 License.
|
49 |
+
See [LICENSE](LICENSE) for more information.
|
50 |
+
|
51 |
+
```python
|
52 |
+
# Copyright (C) 2024-present Naver Corporation. All rights reserved.
|
53 |
+
# Licensed under CC BY-NC-SA 4.0 (non-commercial use only).
|
54 |
+
```
|
55 |
+
|
56 |
+
## Get Started
|
57 |
+
|
58 |
+
### Installation
|
59 |
+
|
60 |
+
1. Clone MASt3R.
|
61 |
+
```bash
|
62 |
+
git clone --recursive https://github.com/naver/mast3r
|
63 |
+
cd mast3r
|
64 |
+
# if you have already cloned mast3r:
|
65 |
+
# git submodule update --init --recursive
|
66 |
+
```
|
67 |
+
|
68 |
+
2. Create the environment, here we show an example using conda.
|
69 |
+
```bash
|
70 |
+
conda create -n mast3r python=3.11 cmake=3.14.0
|
71 |
+
conda activate mast3r
|
72 |
+
conda install pytorch torchvision pytorch-cuda=12.1 -c pytorch -c nvidia # use the correct version of cuda for your system
|
73 |
+
pip install -r requirements.txt
|
74 |
+
pip install -r dust3r/requirements.txt
|
75 |
+
# Optional: you can also install additional packages to:
|
76 |
+
# - add support for HEIC images
|
77 |
+
# - add required packages for visloc.py
|
78 |
+
pip install -r dust3r/requirements_optional.txt
|
79 |
+
```
|
80 |
+
|
81 |
+
3. Optional, compile the cuda kernels for RoPE (as in CroCo v2).
|
82 |
+
```bash
|
83 |
+
# DUST3R relies on RoPE positional embeddings for which you can compile some cuda kernels for faster runtime.
|
84 |
+
cd dust3r/croco/models/curope/
|
85 |
+
python setup.py build_ext --inplace
|
86 |
+
cd ../../../../
|
87 |
+
```
|
88 |
+
|
89 |
+
|
90 |
+
### Checkpoints
|
91 |
+
|
92 |
+
You can obtain the checkpoints by two ways:
|
93 |
+
|
94 |
+
1) You can use our huggingface_hub integration: the models will be downloaded automatically.
|
95 |
+
|
96 |
+
2) Otherwise, We provide several pre-trained models:
|
97 |
+
|
98 |
+
| Modelname | Training resolutions | Head | Encoder | Decoder |
|
99 |
+
|-------------|----------------------|------|---------|---------|
|
100 |
+
| [`MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric`](https://download.europe.naverlabs.com/ComputerVision/MASt3R/MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric.pth) | 512x384, 512x336, 512x288, 512x256, 512x160 | CatMLP+DPT | ViT-L | ViT-B |
|
101 |
+
|
102 |
+
You can check the hyperparameters we used to train these models in the [section: Our Hyperparameters](#our-hyperparameters)
|
103 |
+
Make sure to check license of the datasets we used.
|
104 |
+
|
105 |
+
To download a specific model, for example `MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric.pth`:
|
106 |
+
```bash
|
107 |
+
mkdir -p checkpoints/
|
108 |
+
wget https://download.europe.naverlabs.com/ComputerVision/MASt3R/MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric.pth -P checkpoints/
|
109 |
+
```
|
110 |
+
|
111 |
+
For these checkpoints, make sure to agree to the license of all the training datasets we used, in addition to CC-BY-NC-SA 4.0.
|
112 |
+
The mapfree dataset license in particular is very restrictive. For more information, check [CHECKPOINTS_NOTICE](CHECKPOINTS_NOTICE).
|
113 |
+
|
114 |
+
|
115 |
+
### Interactive demo
|
116 |
+
|
117 |
+
There are two demos available:
|
118 |
+
|
119 |
+
```
|
120 |
+
demo.py is the updated demo for MASt3R. It uses our new sparse global alignment method that allows you to reconstruct larger scenes
|
121 |
+
|
122 |
+
python3 demo.py --model_name MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric
|
123 |
+
|
124 |
+
# Use --weights to load a checkpoint from a local file, eg --weights checkpoints/MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric.pth
|
125 |
+
# Use --local_network to make it accessible on the local network, or --server_name to specify the url manually
|
126 |
+
# Use --server_port to change the port, by default it will search for an available port starting at 7860
|
127 |
+
# Use --device to use a different device, by default it's "cuda"
|
128 |
+
|
129 |
+
demo_dust3r_ga.py is the same demo as in dust3r (+ compatibility for MASt3R models)
|
130 |
+
see https://github.com/naver/dust3r?tab=readme-ov-file#interactive-demo for details
|
131 |
+
```
|
132 |
+
### Interactive demo with docker
|
133 |
+
|
134 |
+
TODO
|
135 |
+
|
136 |
+
![demo](assets/demo.jpg)
|
137 |
+
|
138 |
+
## Usage
|
139 |
+
|
140 |
+
```python
|
141 |
+
from mast3r.model import AsymmetricMASt3R
|
142 |
+
from mast3r.fast_nn import fast_reciprocal_NNs
|
143 |
+
|
144 |
+
import mast3r.utils.path_to_dust3r
|
145 |
+
from dust3r.inference import inference
|
146 |
+
from dust3r.utils.image import load_images
|
147 |
+
|
148 |
+
if __name__ == '__main__':
|
149 |
+
device = 'cuda'
|
150 |
+
schedule = 'cosine'
|
151 |
+
lr = 0.01
|
152 |
+
niter = 300
|
153 |
+
|
154 |
+
model_name = "naver/MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric"
|
155 |
+
# you can put the path to a local checkpoint in model_name if needed
|
156 |
+
model = AsymmetricMASt3R.from_pretrained(model_name).to(device)
|
157 |
+
images = load_images(['dust3r/croco/assets/Chateau1.png', 'dust3r/croco/assets/Chateau2.png'], size=512)
|
158 |
+
output = inference([tuple(images)], model, device, batch_size=1, verbose=False)
|
159 |
+
|
160 |
+
# at this stage, you have the raw dust3r predictions
|
161 |
+
view1, pred1 = output['view1'], output['pred1']
|
162 |
+
view2, pred2 = output['view2'], output['pred2']
|
163 |
+
|
164 |
+
desc1, desc2 = pred1['desc'].squeeze(0).detach(), pred2['desc'].squeeze(0).detach()
|
165 |
+
|
166 |
+
# find 2D-2D matches between the two images
|
167 |
+
matches_im0, matches_im1 = fast_reciprocal_NNs(desc1, desc2, subsample_or_initxy1=8,
|
168 |
+
device=device, dist='dot', block_size=2**13)
|
169 |
+
|
170 |
+
# ignore small border around the edge
|
171 |
+
H0, W0 = view1['true_shape'][0]
|
172 |
+
valid_matches_im0 = (matches_im0[:, 0] >= 3) & (matches_im0[:, 0] < int(W0) - 3) & (
|
173 |
+
matches_im0[:, 1] >= 3) & (matches_im0[:, 1] < int(H0) - 3)
|
174 |
+
|
175 |
+
H1, W1 = view2['true_shape'][0]
|
176 |
+
valid_matches_im1 = (matches_im1[:, 0] >= 3) & (matches_im1[:, 0] < int(W1) - 3) & (
|
177 |
+
matches_im1[:, 1] >= 3) & (matches_im1[:, 1] < int(H1) - 3)
|
178 |
+
|
179 |
+
valid_matches = valid_matches_im0 & valid_matches_im1
|
180 |
+
matches_im0, matches_im1 = matches_im0[valid_matches], matches_im1[valid_matches]
|
181 |
+
|
182 |
+
# visualize a few matches
|
183 |
+
import numpy as np
|
184 |
+
import torch
|
185 |
+
import torchvision.transforms.functional
|
186 |
+
from matplotlib import pyplot as pl
|
187 |
+
|
188 |
+
n_viz = 20
|
189 |
+
num_matches = matches_im0.shape[0]
|
190 |
+
match_idx_to_viz = np.round(np.linspace(0, num_matches - 1, n_viz)).astype(int)
|
191 |
+
viz_matches_im0, viz_matches_im1 = matches_im0[match_idx_to_viz], matches_im1[match_idx_to_viz]
|
192 |
+
|
193 |
+
image_mean = torch.as_tensor([0.5, 0.5, 0.5], device='cpu').reshape(1, 3, 1, 1)
|
194 |
+
image_std = torch.as_tensor([0.5, 0.5, 0.5], device='cpu').reshape(1, 3, 1, 1)
|
195 |
+
|
196 |
+
viz_imgs = []
|
197 |
+
for i, view in enumerate([view1, view2]):
|
198 |
+
rgb_tensor = view['img'] * image_std + image_mean
|
199 |
+
viz_imgs.append(rgb_tensor.squeeze(0).permute(1, 2, 0).cpu().numpy())
|
200 |
+
|
201 |
+
H0, W0, H1, W1 = *viz_imgs[0].shape[:2], *viz_imgs[1].shape[:2]
|
202 |
+
img0 = np.pad(viz_imgs[0], ((0, max(H1 - H0, 0)), (0, 0), (0, 0)), 'constant', constant_values=0)
|
203 |
+
img1 = np.pad(viz_imgs[1], ((0, max(H0 - H1, 0)), (0, 0), (0, 0)), 'constant', constant_values=0)
|
204 |
+
img = np.concatenate((img0, img1), axis=1)
|
205 |
+
pl.figure()
|
206 |
+
pl.imshow(img)
|
207 |
+
cmap = pl.get_cmap('jet')
|
208 |
+
for i in range(n_viz):
|
209 |
+
(x0, y0), (x1, y1) = viz_matches_im0[i].T, viz_matches_im1[i].T
|
210 |
+
pl.plot([x0, x1 + W0], [y0, y1], '-+', color=cmap(i / (n_viz - 1)), scalex=False, scaley=False)
|
211 |
+
pl.show(block=True)
|
212 |
+
```
|
213 |
+
![matching example on croco pair](assets/matching.jpg)
|
214 |
+
|
215 |
+
## Training
|
216 |
+
|
217 |
+
In this section, we present a short demonstration to get started with training MASt3R.
|
218 |
+
|
219 |
+
### Datasets
|
220 |
+
|
221 |
+
See [Datasets section in DUSt3R](https://github.com/naver/dust3r/tree/datasets?tab=readme-ov-file#datasets)
|
222 |
+
|
223 |
+
### Demo
|
224 |
+
|
225 |
+
Like for the DUSt3R training demo, we're going to download and prepare the same subset of [CO3Dv2](https://github.com/facebookresearch/co3d) - [Creative Commons Attribution-NonCommercial 4.0 International](https://github.com/facebookresearch/co3d/blob/main/LICENSE) and launch the training code on it.
|
226 |
+
It is the exact same process as DUSt3R.
|
227 |
+
The demo model will be trained for a few epochs on a very small dataset.
|
228 |
+
It will not be very good.
|
229 |
+
|
230 |
+
```bash
|
231 |
+
# download and prepare the co3d subset
|
232 |
+
mkdir -p data/co3d_subset
|
233 |
+
cd data/co3d_subset
|
234 |
+
git clone https://github.com/facebookresearch/co3d
|
235 |
+
cd co3d
|
236 |
+
python3 ./co3d/download_dataset.py --download_folder ../ --single_sequence_subset
|
237 |
+
rm ../*.zip
|
238 |
+
cd ../../..
|
239 |
+
|
240 |
+
python3 datasets_preprocess/preprocess_co3d.py --co3d_dir data/co3d_subset --output_dir data/co3d_subset_processed --single_sequence_subset
|
241 |
+
|
242 |
+
# download the pretrained dust3r checkpoint
|
243 |
+
mkdir -p checkpoints/
|
244 |
+
wget https://download.europe.naverlabs.com/ComputerVision/DUSt3R/DUSt3R_ViTLarge_BaseDecoder_512_dpt.pth -P checkpoints/
|
245 |
+
|
246 |
+
# for this example we'll do fewer epochs, for the actual hyperparameters we used in the paper, see the next section: "Our Hyperparameters"
|
247 |
+
torchrun --nproc_per_node=4 train.py \
|
248 |
+
--train_dataset "1000 @ Co3d(split='train', ROOT='data/co3d_subset_processed', aug_crop='auto', aug_monocular=0.005, aug_rot90='diff', mask_bg='rand', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], n_corres=8192, nneg=0.5, transform=ColorJitter)" \
|
249 |
+
--test_dataset "100 @ Co3d(split='test', ROOT='data/co3d_subset_processed', resolution=(512,384), n_corres=1024, seed=777)" \
|
250 |
+
--model "AsymmetricMASt3R(pos_embed='RoPE100', patch_embed_cls='ManyAR_PatchEmbed', img_size=(512, 512), head_type='catmlp+dpt', output_mode='pts3d+desc24', depth_mode=('exp', -inf, inf), conf_mode=('exp', 1, inf), enc_embed_dim=1024, enc_depth=24, enc_num_heads=16, dec_embed_dim=768, dec_depth=12, dec_num_heads=12, two_confs=True)" \
|
251 |
+
--train_criterion "ConfLoss(Regr3D(L21, norm_mode='?avg_dis'), alpha=0.2) + 0.075*ConfMatchingLoss(MatchingLoss(InfoNCE(mode='proper', temperature=0.05), negatives_padding=0, blocksize=8192), alpha=10.0, confmode='mean')" \
|
252 |
+
--test_criterion "Regr3D_ScaleShiftInv(L21, norm_mode='?avg_dis', gt_scale=True, sky_loss_value=0) + -1.*MatchingLoss(APLoss(nq='torch', fp=torch.float16), negatives_padding=12288)" \
|
253 |
+
--pretrained "checkpoints/DUSt3R_ViTLarge_BaseDecoder_512_dpt.pth" \
|
254 |
+
--lr 0.0001 --min_lr 1e-06 --warmup_epochs 1 --epochs 10 --batch_size 4 --accum_iter 4 \
|
255 |
+
--save_freq 1 --keep_freq 5 --eval_freq 1 \
|
256 |
+
--output_dir "checkpoints/mast3r_demo"
|
257 |
+
|
258 |
+
```
|
259 |
+
|
260 |
+
### Our Hyperparameters
|
261 |
+
We didn't release all the training datasets, but here are the commands we used for training our models:
|
262 |
+
|
263 |
+
```bash
|
264 |
+
# MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric - train mast3r with metric regression and matching loss
|
265 |
+
# we used cosxl to generate variations of DL3DV: "foggy", "night", "rainy", "snow", "sunny" but we were not convinced by it.
|
266 |
+
|
267 |
+
torchrun --nproc_per_node=8 train.py \
|
268 |
+
--train_dataset "57_000 @ Habitat512(1_000_000, split='train', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 68_400 @ BlendedMVS(split='train', mask_sky=True, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 68_400 @ MegaDepth(split='train', mask_sky=True, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 45_600 @ ARKitScenes(split='train', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 22_800 @ Co3d(split='train', mask_bg='rand', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 22_800 @ StaticThings3D(mask_bg='rand', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 45_600 @ ScanNetpp(split='train', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 45_600 @ TartanAir(pairs_subset='', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 4_560 @ UnrealStereo4K(resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 1_140 @ VirtualKitti(optical_center_is_centered=True, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 22_800 @ WildRgbd(split='train', mask_bg='rand', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 145_920 @ NianticMapFree(split='train', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 57_000 @ DL3DV(split='nlight', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 57_000 @ DL3DV(split='not-nlight', cosxl_augmentations=None, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5) + 34_200 @ InternalUnreleasedDataset(resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], aug_crop='auto', aug_monocular=0.005, transform=ColorJitter, n_corres=8192, nneg=0.5)" \
|
269 |
+
--test_dataset "Habitat512(1_000, split='val', resolution=(512,384), seed=777, n_corres=1024) + 1_000 @ BlendedMVS(split='val', resolution=(512,384), mask_sky=True, seed=777, n_corres=1024) + 1_000 @ ARKitScenes(split='test', resolution=(512,384), seed=777, n_corres=1024) + 1_000 @ MegaDepth(split='val', mask_sky=True, resolution=(512,336), seed=777, n_corres=1024) + 1_000 @ Co3d(split='test', resolution=(512,384), mask_bg='rand', seed=777, n_corres=1024)" \
|
270 |
+
--model "AsymmetricMASt3R(pos_embed='RoPE100', patch_embed_cls='ManyAR_PatchEmbed', img_size=(512, 512), head_type='catmlp+dpt', output_mode='pts3d+desc24', depth_mode=('exp', -inf, inf), conf_mode=('exp', 1, inf), enc_embed_dim=1024, enc_depth=24, enc_num_heads=16, dec_embed_dim=768, dec_depth=12, dec_num_heads=12, two_confs=True, desc_conf_mode=('exp', 0, inf))" \
|
271 |
+
--train_criterion "ConfLoss(Regr3D(L21, norm_mode='?avg_dis'), alpha=0.2, loss_in_log=False) + 0.075*ConfMatchingLoss(MatchingLoss(InfoNCE(mode='proper', temperature=0.05), negatives_padding=0, blocksize=8192), alpha=10.0, confmode='mean')" \
|
272 |
+
--test_criterion "Regr3D(L21, norm_mode='?avg_dis', gt_scale=True, sky_loss_value=0) + -1.*MatchingLoss(APLoss(nq='torch', fp=torch.float16), negatives_padding=12288)" \
|
273 |
+
--pretrained "checkpoints/DUSt3R_ViTLarge_BaseDecoder_512_dpt.pth" \
|
274 |
+
--lr 0.0001 --min_lr 1e-06 --warmup_epochs 8 --epochs 50 --batch_size 4 --accum_iter 2 \
|
275 |
+
--save_freq 1 --keep_freq 5 --eval_freq 1 --print_freq=10 \
|
276 |
+
--output_dir "checkpoints/MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric"
|
277 |
+
|
278 |
+
```
|
279 |
+
|
280 |
+
## Visual Localization
|
281 |
+
|
282 |
+
### Dataset preparation
|
283 |
+
|
284 |
+
See [Visloc section in DUSt3R](https://github.com/naver/dust3r/tree/dust3r_visloc#dataset-preparation)
|
285 |
+
|
286 |
+
### Example Commands
|
287 |
+
|
288 |
+
With `visloc.py` you can run our visual localization experiments on Aachen-Day-Night, InLoc, Cambridge Landmarks and 7 Scenes.
|
289 |
+
|
290 |
+
|
291 |
+
```bash
|
292 |
+
# Aachen-Day-Night-v1.1:
|
293 |
+
# scene in 'day' 'night'
|
294 |
+
# scene can also be 'all'
|
295 |
+
python3 visloc.py --model_name MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric --dataset "VislocAachenDayNight('/path/to/prepared/Aachen-Day-Night-v1.1/', subscene='${scene}', pairsfile='fire_top50', topk=20)" --pixel_tol 5 --pnp_mode poselib --reprojection_error_diag_ratio 0.008 --output_dir /path/to/output/Aachen-Day-Night-v1.1/${scene}/loc
|
296 |
+
|
297 |
+
# or with coarse to fine:
|
298 |
+
|
299 |
+
python3 visloc.py --model_name MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric --dataset "VislocAachenDayNight('/path/to/prepared/Aachen-Day-Night-v1.1/', subscene='${scene}', pairsfile='fire_top50', topk=20)" --pixel_tol 5 --pnp_mode poselib --reprojection_error_diag_ratio 0.008 --output_dir /path/to/output/Aachen-Day-Night-v1.1/${scene}/loc --coarse_to_fine --max_batch_size 48 --c2f_crop_with_homography
|
300 |
+
|
301 |
+
# InLoc
|
302 |
+
python3 visloc.py --model_name MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric --dataset "VislocInLoc('/path/to/prepared/InLoc/', pairsfile='pairs-query-netvlad40-temporal', topk=20)" --pixel_tol 5 --pnp_mode poselib --reprojection_error_diag_ratio 0.008 --output_dir /path/to/output/InLoc/loc
|
303 |
+
|
304 |
+
# or with coarse to fine:
|
305 |
+
|
306 |
+
python3 visloc.py --model_name MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric --dataset "VislocInLoc('/path/to/prepared/InLoc/', pairsfile='pairs-query-netvlad40-temporal', topk=20)" --pixel_tol 5 --pnp_mode poselib --reprojection_error_diag_ratio 0.008 --output_dir /path/to/output/InLoc/loc --coarse_to_fine --max_image_size 1200 --max_batch_size 48 --c2f_crop_with_homography
|
307 |
+
|
308 |
+
# 7-scenes:
|
309 |
+
# scene in 'chess' 'fire' 'heads' 'office' 'pumpkin' 'redkitchen' 'stairs'
|
310 |
+
python3 visloc.py --model_name MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric --dataset "VislocSevenScenes('/path/to/prepared/7-scenes/', subscene='${scene}', pairsfile='APGeM-LM18_top20', topk=1)" --pixel_tol 5 --pnp_mode poselib --reprojection_error_diag_ratio 0.008 --output_dir /path/to/output/7-scenes/${scene}/loc
|
311 |
+
|
312 |
+
# Cambridge Landmarks:
|
313 |
+
# scene in 'ShopFacade' 'GreatCourt' 'KingsCollege' 'OldHospital' 'StMarysChurch'
|
314 |
+
python3 visloc.py --model_name MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric --dataset "VislocCambridgeLandmarks('/path/to/prepared/Cambridge_Landmarks/', subscene='${scene}', pairsfile='APGeM-LM18_top20', topk=1)" --pixel_tol 5 --pnp_mode poselib --reprojection_error_diag_ratio 0.008 --output_dir /path/to/output/Cambridge_Landmarks/${scene}/loc
|
315 |
+
|
316 |
+
```
|
third_party/mast3r/assets/NLE_tower/01D90321-69C8-439F-B0B0-E87E7634741C-83120-000041DAE419D7AE.jpg
ADDED
Git LFS Details
|
third_party/mast3r/assets/NLE_tower/1AD85EF5-B651-4291-A5C0-7BDB7D966384-83120-000041DADF639E09.jpg
ADDED
Git LFS Details
|
third_party/mast3r/assets/NLE_tower/2679C386-1DC0-4443-81B5-93D7EDE4AB37-83120-000041DADB2EA917.jpg
ADDED
Git LFS Details
|
third_party/mast3r/assets/NLE_tower/28EDBB63-B9F9-42FB-AC86-4852A33ED71B-83120-000041DAF22407A1.jpg
ADDED
Git LFS Details
|
third_party/mast3r/assets/NLE_tower/91E9B685-7A7D-42D7-B933-23A800EE4129-83120-000041DAE12C8176.jpg
ADDED
Git LFS Details
|
third_party/mast3r/assets/NLE_tower/CDBBD885-54C3-4EB4-9181-226059A60EE0-83120-000041DAE0C3D612.jpg
ADDED
Git LFS Details
|
third_party/mast3r/assets/NLE_tower/FF5599FD-768B-431A-AB83-BDA5FB44CB9D-83120-000041DADDE35483.jpg
ADDED
Git LFS Details
|
third_party/mast3r/assets/demo.jpg
ADDED
Git LFS Details
|
third_party/mast3r/assets/examples.jpg
ADDED
Git LFS Details
|
third_party/mast3r/assets/mast3r.jpg
ADDED
Git LFS Details
|
third_party/mast3r/assets/mast3r_archi.jpg
ADDED
Git LFS Details
|
third_party/mast3r/assets/matching.jpg
ADDED
Git LFS Details
|
third_party/mast3r/demo.py
ADDED
@@ -0,0 +1,290 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
# Copyright (C) 2024-present Naver Corporation. All rights reserved.
|
3 |
+
# Licensed under CC BY-NC-SA 4.0 (non-commercial use only).
|
4 |
+
#
|
5 |
+
# --------------------------------------------------------
|
6 |
+
# gradio demo
|
7 |
+
# --------------------------------------------------------
|
8 |
+
import math
|
9 |
+
import gradio
|
10 |
+
import os
|
11 |
+
import torch
|
12 |
+
import numpy as np
|
13 |
+
import tempfile
|
14 |
+
import functools
|
15 |
+
import trimesh
|
16 |
+
import copy
|
17 |
+
from scipy.spatial.transform import Rotation
|
18 |
+
|
19 |
+
from mast3r.cloud_opt.sparse_ga import sparse_global_alignment
|
20 |
+
from mast3r.cloud_opt.tsdf_optimizer import TSDFPostProcess
|
21 |
+
|
22 |
+
from mast3r.model import AsymmetricMASt3R
|
23 |
+
from mast3r.utils.misc import hash_md5
|
24 |
+
import mast3r.utils.path_to_dust3r # noqa
|
25 |
+
from dust3r.image_pairs import make_pairs
|
26 |
+
from dust3r.utils.image import load_images
|
27 |
+
from dust3r.utils.device import to_numpy
|
28 |
+
from dust3r.viz import add_scene_cam, CAM_COLORS, OPENGL, pts3d_to_trimesh, cat_meshes
|
29 |
+
from dust3r.demo import get_args_parser as dust3r_get_args_parser
|
30 |
+
|
31 |
+
import matplotlib.pyplot as pl
|
32 |
+
pl.ion()
|
33 |
+
|
34 |
+
torch.backends.cuda.matmul.allow_tf32 = True # for gpu >= Ampere and pytorch >= 1.12
|
35 |
+
batch_size = 1
|
36 |
+
|
37 |
+
|
38 |
+
def get_args_parser():
|
39 |
+
parser = dust3r_get_args_parser()
|
40 |
+
parser.add_argument('--share', action='store_true')
|
41 |
+
|
42 |
+
actions = parser._actions
|
43 |
+
for action in actions:
|
44 |
+
if action.dest == 'model_name':
|
45 |
+
action.choices = ["MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric"]
|
46 |
+
# change defaults
|
47 |
+
parser.prog = 'mast3r demo'
|
48 |
+
return parser
|
49 |
+
|
50 |
+
|
51 |
+
def _convert_scene_output_to_glb(outdir, imgs, pts3d, mask, focals, cams2world, cam_size=0.05,
|
52 |
+
cam_color=None, as_pointcloud=False,
|
53 |
+
transparent_cams=False, silent=False):
|
54 |
+
assert len(pts3d) == len(mask) <= len(imgs) <= len(cams2world) == len(focals)
|
55 |
+
pts3d = to_numpy(pts3d)
|
56 |
+
imgs = to_numpy(imgs)
|
57 |
+
focals = to_numpy(focals)
|
58 |
+
cams2world = to_numpy(cams2world)
|
59 |
+
|
60 |
+
scene = trimesh.Scene()
|
61 |
+
|
62 |
+
# full pointcloud
|
63 |
+
if as_pointcloud:
|
64 |
+
pts = np.concatenate([p[m.ravel()] for p, m in zip(pts3d, mask)])
|
65 |
+
col = np.concatenate([p[m] for p, m in zip(imgs, mask)])
|
66 |
+
pct = trimesh.PointCloud(pts.reshape(-1, 3), colors=col.reshape(-1, 3))
|
67 |
+
scene.add_geometry(pct)
|
68 |
+
else:
|
69 |
+
meshes = []
|
70 |
+
for i in range(len(imgs)):
|
71 |
+
meshes.append(pts3d_to_trimesh(imgs[i], pts3d[i].reshape(imgs[i].shape), mask[i]))
|
72 |
+
mesh = trimesh.Trimesh(**cat_meshes(meshes))
|
73 |
+
scene.add_geometry(mesh)
|
74 |
+
|
75 |
+
# add each camera
|
76 |
+
for i, pose_c2w in enumerate(cams2world):
|
77 |
+
if isinstance(cam_color, list):
|
78 |
+
camera_edge_color = cam_color[i]
|
79 |
+
else:
|
80 |
+
camera_edge_color = cam_color or CAM_COLORS[i % len(CAM_COLORS)]
|
81 |
+
add_scene_cam(scene, pose_c2w, camera_edge_color,
|
82 |
+
None if transparent_cams else imgs[i], focals[i],
|
83 |
+
imsize=imgs[i].shape[1::-1], screen_width=cam_size)
|
84 |
+
|
85 |
+
rot = np.eye(4)
|
86 |
+
rot[:3, :3] = Rotation.from_euler('y', np.deg2rad(180)).as_matrix()
|
87 |
+
scene.apply_transform(np.linalg.inv(cams2world[0] @ OPENGL @ rot))
|
88 |
+
outfile = os.path.join(outdir, 'scene.glb')
|
89 |
+
if not silent:
|
90 |
+
print('(exporting 3D scene to', outfile, ')')
|
91 |
+
scene.export(file_obj=outfile)
|
92 |
+
return outfile
|
93 |
+
|
94 |
+
|
95 |
+
def get_3D_model_from_scene(outdir, silent, scene, min_conf_thr=2, as_pointcloud=False, mask_sky=False,
|
96 |
+
clean_depth=False, transparent_cams=False, cam_size=0.05, TSDF_thresh=0):
|
97 |
+
"""
|
98 |
+
extract 3D_model (glb file) from a reconstructed scene
|
99 |
+
"""
|
100 |
+
if scene is None:
|
101 |
+
return None
|
102 |
+
|
103 |
+
# get optimized values from scene
|
104 |
+
rgbimg = scene.imgs
|
105 |
+
focals = scene.get_focals().cpu()
|
106 |
+
cams2world = scene.get_im_poses().cpu()
|
107 |
+
|
108 |
+
# 3D pointcloud from depthmap, poses and intrinsics
|
109 |
+
if TSDF_thresh > 0:
|
110 |
+
tsdf = TSDFPostProcess(scene, TSDF_thresh=TSDF_thresh)
|
111 |
+
pts3d, _, confs = to_numpy(tsdf.get_dense_pts3d(clean_depth=clean_depth))
|
112 |
+
else:
|
113 |
+
pts3d, _, confs = to_numpy(scene.get_dense_pts3d(clean_depth=clean_depth))
|
114 |
+
msk = to_numpy([c > min_conf_thr for c in confs])
|
115 |
+
return _convert_scene_output_to_glb(outdir, rgbimg, pts3d, msk, focals, cams2world, as_pointcloud=as_pointcloud,
|
116 |
+
transparent_cams=transparent_cams, cam_size=cam_size, silent=silent)
|
117 |
+
|
118 |
+
|
119 |
+
def get_reconstructed_scene(outdir, model, device, silent, image_size, filelist, optim_level, lr1, niter1, lr2, niter2, min_conf_thr,
|
120 |
+
as_pointcloud, mask_sky, clean_depth, transparent_cams, cam_size,
|
121 |
+
scenegraph_type, winsize, refid, TSDF_thresh, **kw):
|
122 |
+
"""
|
123 |
+
from a list of images, run mast3r inference, sparse global aligner.
|
124 |
+
then run get_3D_model_from_scene
|
125 |
+
"""
|
126 |
+
imgs = load_images(filelist, size=image_size, verbose=not silent)
|
127 |
+
if len(imgs) == 1:
|
128 |
+
imgs = [imgs[0], copy.deepcopy(imgs[0])]
|
129 |
+
imgs[1]['idx'] = 1
|
130 |
+
filelist = [filelist[0], filelist[0] + '_2']
|
131 |
+
if scenegraph_type == "swin":
|
132 |
+
scenegraph_type = scenegraph_type + "-" + str(winsize)
|
133 |
+
elif scenegraph_type == "oneref":
|
134 |
+
scenegraph_type = scenegraph_type + "-" + str(refid)
|
135 |
+
|
136 |
+
pairs = make_pairs(imgs, scene_graph=scenegraph_type, prefilter=None, symmetrize=True)
|
137 |
+
if optim_level == 'coarse':
|
138 |
+
niter2 = 0
|
139 |
+
# Sparse GA (forward mast3r -> matching -> 3D optim -> 2D refinement -> triangulation)
|
140 |
+
scene = sparse_global_alignment(filelist, pairs, os.path.join(outdir, 'cache'),
|
141 |
+
model, lr1=lr1, niter1=niter1, lr2=lr2, niter2=niter2, device=device,
|
142 |
+
opt_depth='depth' in optim_level, **kw)
|
143 |
+
outfile = get_3D_model_from_scene(outdir, silent, scene, min_conf_thr, as_pointcloud, mask_sky,
|
144 |
+
clean_depth, transparent_cams, cam_size, TSDF_thresh)
|
145 |
+
return scene, outfile
|
146 |
+
|
147 |
+
|
148 |
+
def set_scenegraph_options(inputfiles, winsize, refid, scenegraph_type):
|
149 |
+
num_files = len(inputfiles) if inputfiles is not None else 1
|
150 |
+
max_winsize = max(1, math.ceil((num_files - 1) / 2))
|
151 |
+
if scenegraph_type == "swin":
|
152 |
+
winsize = gradio.Slider(label="Scene Graph: Window Size", value=max_winsize,
|
153 |
+
minimum=1, maximum=max_winsize, step=1, visible=True)
|
154 |
+
refid = gradio.Slider(label="Scene Graph: Id", value=0, minimum=0,
|
155 |
+
maximum=num_files - 1, step=1, visible=False)
|
156 |
+
elif scenegraph_type == "oneref":
|
157 |
+
winsize = gradio.Slider(label="Scene Graph: Window Size", value=max_winsize,
|
158 |
+
minimum=1, maximum=max_winsize, step=1, visible=False)
|
159 |
+
refid = gradio.Slider(label="Scene Graph: Id", value=0, minimum=0,
|
160 |
+
maximum=num_files - 1, step=1, visible=True)
|
161 |
+
else:
|
162 |
+
winsize = gradio.Slider(label="Scene Graph: Window Size", value=max_winsize,
|
163 |
+
minimum=1, maximum=max_winsize, step=1, visible=False)
|
164 |
+
refid = gradio.Slider(label="Scene Graph: Id", value=0, minimum=0,
|
165 |
+
maximum=num_files - 1, step=1, visible=False)
|
166 |
+
return winsize, refid
|
167 |
+
|
168 |
+
|
169 |
+
def main_demo(tmpdirname, model, device, image_size, server_name, server_port, silent=False, share=False):
|
170 |
+
if not silent:
|
171 |
+
print('Outputing stuff in', tmpdirname)
|
172 |
+
|
173 |
+
recon_fun = functools.partial(get_reconstructed_scene, tmpdirname, model, device, silent, image_size)
|
174 |
+
model_from_scene_fun = functools.partial(get_3D_model_from_scene, tmpdirname, silent)
|
175 |
+
with gradio.Blocks(css=""".gradio-container {margin: 0 !important; min-width: 100%};""", title="MASt3R Demo") as demo:
|
176 |
+
# scene state is save so that you can change conf_thr, cam_size... without rerunning the inference
|
177 |
+
scene = gradio.State(None)
|
178 |
+
gradio.HTML('<h2 style="text-align: center;">MASt3R Demo</h2>')
|
179 |
+
with gradio.Column():
|
180 |
+
inputfiles = gradio.File(file_count="multiple")
|
181 |
+
with gradio.Row():
|
182 |
+
lr1 = gradio.Slider(label="Coarse LR", value=0.07, minimum=0.01, maximum=0.2, step=0.01)
|
183 |
+
niter1 = gradio.Number(value=200, precision=0, minimum=0, maximum=10_000,
|
184 |
+
label="num_iterations", info="For coarse alignment!")
|
185 |
+
lr2 = gradio.Slider(label="Fine LR", value=0.014, minimum=0.005, maximum=0.05, step=0.001)
|
186 |
+
niter2 = gradio.Number(value=500, precision=0, minimum=0, maximum=100_000,
|
187 |
+
label="num_iterations", info="For refinement!")
|
188 |
+
optim_level = gradio.Dropdown(["coarse", "refine", "refine+depth"],
|
189 |
+
value='refine', label="OptLevel",
|
190 |
+
info="Optimization level")
|
191 |
+
|
192 |
+
scenegraph_type = gradio.Dropdown(["complete", "swin", "oneref"],
|
193 |
+
value='complete', label="Scenegraph",
|
194 |
+
info="Define how to make pairs",
|
195 |
+
interactive=True)
|
196 |
+
winsize = gradio.Slider(label="Scene Graph: Window Size", value=1,
|
197 |
+
minimum=1, maximum=1, step=1, visible=False)
|
198 |
+
refid = gradio.Slider(label="Scene Graph: Id", value=0, minimum=0, maximum=0, step=1, visible=False)
|
199 |
+
|
200 |
+
run_btn = gradio.Button("Run")
|
201 |
+
|
202 |
+
with gradio.Row():
|
203 |
+
# adjust the confidence threshold
|
204 |
+
min_conf_thr = gradio.Slider(label="min_conf_thr", value=1.5, minimum=0.0, maximum=10, step=0.1)
|
205 |
+
# adjust the camera size in the output pointcloud
|
206 |
+
cam_size = gradio.Slider(label="cam_size", value=0.2, minimum=0.001, maximum=1.0, step=0.001)
|
207 |
+
TSDF_thresh = gradio.Slider(label="TSDF Threshold", value=0., minimum=0., maximum=1., step=0.01)
|
208 |
+
with gradio.Row():
|
209 |
+
as_pointcloud = gradio.Checkbox(value=True, label="As pointcloud")
|
210 |
+
# two post process implemented
|
211 |
+
mask_sky = gradio.Checkbox(value=False, label="Mask sky")
|
212 |
+
clean_depth = gradio.Checkbox(value=True, label="Clean-up depthmaps")
|
213 |
+
transparent_cams = gradio.Checkbox(value=False, label="Transparent cameras")
|
214 |
+
|
215 |
+
outmodel = gradio.Model3D()
|
216 |
+
|
217 |
+
# events
|
218 |
+
scenegraph_type.change(set_scenegraph_options,
|
219 |
+
inputs=[inputfiles, winsize, refid, scenegraph_type],
|
220 |
+
outputs=[winsize, refid])
|
221 |
+
inputfiles.change(set_scenegraph_options,
|
222 |
+
inputs=[inputfiles, winsize, refid, scenegraph_type],
|
223 |
+
outputs=[winsize, refid])
|
224 |
+
run_btn.click(fn=recon_fun,
|
225 |
+
inputs=[inputfiles, optim_level, lr1, niter1, lr2, niter2, min_conf_thr, as_pointcloud,
|
226 |
+
mask_sky, clean_depth, transparent_cams, cam_size,
|
227 |
+
scenegraph_type, winsize, refid, TSDF_thresh],
|
228 |
+
outputs=[scene, outmodel])
|
229 |
+
min_conf_thr.release(fn=model_from_scene_fun,
|
230 |
+
inputs=[scene, min_conf_thr, as_pointcloud, mask_sky,
|
231 |
+
clean_depth, transparent_cams, cam_size, TSDF_thresh],
|
232 |
+
outputs=outmodel)
|
233 |
+
cam_size.change(fn=model_from_scene_fun,
|
234 |
+
inputs=[scene, min_conf_thr, as_pointcloud, mask_sky,
|
235 |
+
clean_depth, transparent_cams, cam_size, TSDF_thresh],
|
236 |
+
outputs=outmodel)
|
237 |
+
TSDF_thresh.change(fn=model_from_scene_fun,
|
238 |
+
inputs=[scene, min_conf_thr, as_pointcloud, mask_sky,
|
239 |
+
clean_depth, transparent_cams, cam_size, TSDF_thresh],
|
240 |
+
outputs=outmodel)
|
241 |
+
as_pointcloud.change(fn=model_from_scene_fun,
|
242 |
+
inputs=[scene, min_conf_thr, as_pointcloud, mask_sky,
|
243 |
+
clean_depth, transparent_cams, cam_size, TSDF_thresh],
|
244 |
+
outputs=outmodel)
|
245 |
+
mask_sky.change(fn=model_from_scene_fun,
|
246 |
+
inputs=[scene, min_conf_thr, as_pointcloud, mask_sky,
|
247 |
+
clean_depth, transparent_cams, cam_size, TSDF_thresh],
|
248 |
+
outputs=outmodel)
|
249 |
+
clean_depth.change(fn=model_from_scene_fun,
|
250 |
+
inputs=[scene, min_conf_thr, as_pointcloud, mask_sky,
|
251 |
+
clean_depth, transparent_cams, cam_size, TSDF_thresh],
|
252 |
+
outputs=outmodel)
|
253 |
+
transparent_cams.change(model_from_scene_fun,
|
254 |
+
inputs=[scene, min_conf_thr, as_pointcloud, mask_sky,
|
255 |
+
clean_depth, transparent_cams, cam_size, TSDF_thresh],
|
256 |
+
outputs=outmodel)
|
257 |
+
demo.launch(share=False, server_name=server_name, server_port=server_port)
|
258 |
+
|
259 |
+
|
260 |
+
if __name__ == '__main__':
|
261 |
+
parser = get_args_parser()
|
262 |
+
args = parser.parse_args()
|
263 |
+
|
264 |
+
if args.server_name is not None:
|
265 |
+
server_name = args.server_name
|
266 |
+
else:
|
267 |
+
server_name = '0.0.0.0' if args.local_network else '127.0.0.1'
|
268 |
+
|
269 |
+
if args.weights is not None:
|
270 |
+
weights_path = args.weights
|
271 |
+
else:
|
272 |
+
weights_path = "naver/" + args.model_name
|
273 |
+
|
274 |
+
model = AsymmetricMASt3R.from_pretrained(weights_path).to(args.device)
|
275 |
+
chkpt_tag = hash_md5(weights_path)
|
276 |
+
|
277 |
+
# mast3r will write the 3D model inside tmpdirname/chkpt_tag
|
278 |
+
if args.tmp_dir is not None:
|
279 |
+
tmpdirname = args.tmp_dir
|
280 |
+
cache_path = os.path.join(tmpdirname, chkpt_tag)
|
281 |
+
os.makedirs(cache_path, exist_ok=True)
|
282 |
+
main_demo(cache_path, model, args.device, args.image_size, server_name, args.server_port, silent=args.silent,
|
283 |
+
share=args.share)
|
284 |
+
else:
|
285 |
+
with tempfile.TemporaryDirectory(suffix='_mast3r_gradio_demo') as tmpdirname:
|
286 |
+
cache_path = os.path.join(tmpdirname, chkpt_tag)
|
287 |
+
os.makedirs(cache_path, exist_ok=True)
|
288 |
+
main_demo(tmpdirname, model, args.device, args.image_size,
|
289 |
+
server_name, args.server_port, silent=args.silent,
|
290 |
+
share=args.share)
|
third_party/mast3r/demo_dust3r_ga.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
# Copyright (C) 2024-present Naver Corporation. All rights reserved.
|
3 |
+
# Licensed under CC BY-NC-SA 4.0 (non-commercial use only).
|
4 |
+
#
|
5 |
+
# --------------------------------------------------------
|
6 |
+
# mast3r gradio demo executable
|
7 |
+
# --------------------------------------------------------
|
8 |
+
import os
|
9 |
+
import torch
|
10 |
+
import tempfile
|
11 |
+
|
12 |
+
import mast3r.utils.path_to_dust3r # noqa
|
13 |
+
from dust3r.model import AsymmetricCroCo3DStereo
|
14 |
+
from mast3r.model import AsymmetricMASt3R
|
15 |
+
from dust3r.demo import get_args_parser as dust3r_get_args_parser
|
16 |
+
from dust3r.demo import main_demo
|
17 |
+
|
18 |
+
import matplotlib.pyplot as pl
|
19 |
+
pl.ion()
|
20 |
+
|
21 |
+
torch.backends.cuda.matmul.allow_tf32 = True # for gpu >= Ampere and pytorch >= 1.12
|
22 |
+
|
23 |
+
|
24 |
+
def get_args_parser():
|
25 |
+
parser = dust3r_get_args_parser()
|
26 |
+
|
27 |
+
actions = parser._actions
|
28 |
+
for action in actions:
|
29 |
+
if action.dest == 'model_name':
|
30 |
+
action.choices.append('MASt3R_ViTLarge_BaseDecoder_512_catmlpdpt_metric')
|
31 |
+
# change defaults
|
32 |
+
parser.prog = 'mast3r demo'
|
33 |
+
return parser
|
34 |
+
|
35 |
+
|
36 |
+
if __name__ == '__main__':
|
37 |
+
parser = get_args_parser()
|
38 |
+
args = parser.parse_args()
|
39 |
+
|
40 |
+
if args.tmp_dir is not None:
|
41 |
+
tmp_path = args.tmp_dir
|
42 |
+
os.makedirs(tmp_path, exist_ok=True)
|
43 |
+
tempfile.tempdir = tmp_path
|
44 |
+
|
45 |
+
if args.server_name is not None:
|
46 |
+
server_name = args.server_name
|
47 |
+
else:
|
48 |
+
server_name = '0.0.0.0' if args.local_network else '127.0.0.1'
|
49 |
+
|
50 |
+
if args.weights is not None:
|
51 |
+
weights_path = args.weights
|
52 |
+
else:
|
53 |
+
weights_path = "naver/" + args.model_name
|
54 |
+
|
55 |
+
try:
|
56 |
+
model = AsymmetricMASt3R.from_pretrained(weights_path).to(args.device)
|
57 |
+
except Exception as e:
|
58 |
+
model = AsymmetricCroCo3DStereo.from_pretrained(weights_path).to(args.device)
|
59 |
+
|
60 |
+
# dust3r will write the 3D model inside tmpdirname
|
61 |
+
with tempfile.TemporaryDirectory(suffix='dust3r_gradio_demo') as tmpdirname:
|
62 |
+
if not args.silent:
|
63 |
+
print('Outputing stuff in', tmpdirname)
|
64 |
+
main_demo(tmpdirname, model, args.device, args.image_size, server_name, args.server_port, silent=args.silent)
|
third_party/mast3r/dust3r/.gitignore
ADDED
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
data/
|
2 |
+
checkpoints/
|
3 |
+
|
4 |
+
# Byte-compiled / optimized / DLL files
|
5 |
+
__pycache__/
|
6 |
+
*.py[cod]
|
7 |
+
*$py.class
|
8 |
+
|
9 |
+
# C extensions
|
10 |
+
*.so
|
11 |
+
|
12 |
+
# Distribution / packaging
|
13 |
+
.Python
|
14 |
+
build/
|
15 |
+
develop-eggs/
|
16 |
+
dist/
|
17 |
+
downloads/
|
18 |
+
eggs/
|
19 |
+
.eggs/
|
20 |
+
lib/
|
21 |
+
lib64/
|
22 |
+
parts/
|
23 |
+
sdist/
|
24 |
+
var/
|
25 |
+
wheels/
|
26 |
+
pip-wheel-metadata/
|
27 |
+
share/python-wheels/
|
28 |
+
*.egg-info/
|
29 |
+
.installed.cfg
|
30 |
+
*.egg
|
31 |
+
MANIFEST
|
32 |
+
|
33 |
+
# PyInstaller
|
34 |
+
# Usually these files are written by a python script from a template
|
35 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
36 |
+
*.manifest
|
37 |
+
*.spec
|
38 |
+
|
39 |
+
# Installer logs
|
40 |
+
pip-log.txt
|
41 |
+
pip-delete-this-directory.txt
|
42 |
+
|
43 |
+
# Unit test / coverage reports
|
44 |
+
htmlcov/
|
45 |
+
.tox/
|
46 |
+
.nox/
|
47 |
+
.coverage
|
48 |
+
.coverage.*
|
49 |
+
.cache
|
50 |
+
nosetests.xml
|
51 |
+
coverage.xml
|
52 |
+
*.cover
|
53 |
+
*.py,cover
|
54 |
+
.hypothesis/
|
55 |
+
.pytest_cache/
|
56 |
+
|
57 |
+
# Translations
|
58 |
+
*.mo
|
59 |
+
*.pot
|
60 |
+
|
61 |
+
# Django stuff:
|
62 |
+
*.log
|
63 |
+
local_settings.py
|
64 |
+
db.sqlite3
|
65 |
+
db.sqlite3-journal
|
66 |
+
|
67 |
+
# Flask stuff:
|
68 |
+
instance/
|
69 |
+
.webassets-cache
|
70 |
+
|
71 |
+
# Scrapy stuff:
|
72 |
+
.scrapy
|
73 |
+
|
74 |
+
# Sphinx documentation
|
75 |
+
docs/_build/
|
76 |
+
|
77 |
+
# PyBuilder
|
78 |
+
target/
|
79 |
+
|
80 |
+
# Jupyter Notebook
|
81 |
+
.ipynb_checkpoints
|
82 |
+
|
83 |
+
# IPython
|
84 |
+
profile_default/
|
85 |
+
ipython_config.py
|
86 |
+
|
87 |
+
# pyenv
|
88 |
+
.python-version
|
89 |
+
|
90 |
+
# pipenv
|
91 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
92 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
93 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
94 |
+
# install all needed dependencies.
|
95 |
+
#Pipfile.lock
|
96 |
+
|
97 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
98 |
+
__pypackages__/
|
99 |
+
|
100 |
+
# Celery stuff
|
101 |
+
celerybeat-schedule
|
102 |
+
celerybeat.pid
|
103 |
+
|
104 |
+
# SageMath parsed files
|
105 |
+
*.sage.py
|
106 |
+
|
107 |
+
# Environments
|
108 |
+
.env
|
109 |
+
.venv
|
110 |
+
env/
|
111 |
+
venv/
|
112 |
+
ENV/
|
113 |
+
env.bak/
|
114 |
+
venv.bak/
|
115 |
+
|
116 |
+
# Spyder project settings
|
117 |
+
.spyderproject
|
118 |
+
.spyproject
|
119 |
+
|
120 |
+
# Rope project settings
|
121 |
+
.ropeproject
|
122 |
+
|
123 |
+
# mkdocs documentation
|
124 |
+
/site
|
125 |
+
|
126 |
+
# mypy
|
127 |
+
.mypy_cache/
|
128 |
+
.dmypy.json
|
129 |
+
dmypy.json
|
130 |
+
|
131 |
+
# Pyre type checker
|
132 |
+
.pyre/
|
third_party/mast3r/dust3r/.gitmodules
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
[submodule "croco"]
|
2 |
+
path = croco
|
3 |
+
url = https://github.com/naver/croco
|
third_party/mast3r/dust3r/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
DUSt3R, Copyright (c) 2024-present Naver Corporation, is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 license.
|
2 |
+
|
3 |
+
A summary of the CC BY-NC-SA 4.0 license is located here:
|
4 |
+
https://creativecommons.org/licenses/by-nc-sa/4.0/
|
5 |
+
|
6 |
+
The CC BY-NC-SA 4.0 license is located here:
|
7 |
+
https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
|
third_party/mast3r/dust3r/NOTICE
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
DUSt3R
|
2 |
+
Copyright 2024-present NAVER Corp.
|
3 |
+
|
4 |
+
This project contains subcomponents with separate copyright notices and license terms.
|
5 |
+
Your use of the source code for these subcomponents is subject to the terms and conditions of the following licenses.
|
6 |
+
|
7 |
+
====
|
8 |
+
|
9 |
+
naver/croco
|
10 |
+
https://github.com/naver/croco/
|
11 |
+
|
12 |
+
Creative Commons Attribution-NonCommercial-ShareAlike 4.0
|
third_party/mast3r/dust3r/README.md
ADDED
@@ -0,0 +1,388 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
![demo](assets/dust3r.jpg)
|
2 |
+
|
3 |
+
Official implementation of `DUSt3R: Geometric 3D Vision Made Easy`
|
4 |
+
[[Project page](https://dust3r.europe.naverlabs.com/)], [[DUSt3R arxiv](https://arxiv.org/abs/2312.14132)]
|
5 |
+
|
6 |
+
![Example of reconstruction from two images](assets/pipeline1.jpg)
|
7 |
+
|
8 |
+
![High level overview of DUSt3R capabilities](assets/dust3r_archi.jpg)
|
9 |
+
|
10 |
+
```bibtex
|
11 |
+
@inproceedings{dust3r_cvpr24,
|
12 |
+
title={DUSt3R: Geometric 3D Vision Made Easy},
|
13 |
+
author={Shuzhe Wang and Vincent Leroy and Yohann Cabon and Boris Chidlovskii and Jerome Revaud},
|
14 |
+
booktitle = {CVPR},
|
15 |
+
year = {2024}
|
16 |
+
}
|
17 |
+
|
18 |
+
@misc{dust3r_arxiv23,
|
19 |
+
title={DUSt3R: Geometric 3D Vision Made Easy},
|
20 |
+
author={Shuzhe Wang and Vincent Leroy and Yohann Cabon and Boris Chidlovskii and Jerome Revaud},
|
21 |
+
year={2023},
|
22 |
+
eprint={2312.14132},
|
23 |
+
archivePrefix={arXiv},
|
24 |
+
primaryClass={cs.CV}
|
25 |
+
}
|
26 |
+
```
|
27 |
+
|
28 |
+
## Table of Contents
|
29 |
+
|
30 |
+
- [Table of Contents](#table-of-contents)
|
31 |
+
- [License](#license)
|
32 |
+
- [Get Started](#get-started)
|
33 |
+
- [Installation](#installation)
|
34 |
+
- [Checkpoints](#checkpoints)
|
35 |
+
- [Interactive demo](#interactive-demo)
|
36 |
+
- [Interactive demo with docker](#interactive-demo-with-docker)
|
37 |
+
- [Usage](#usage)
|
38 |
+
- [Training](#training)
|
39 |
+
- [Datasets](#datasets)
|
40 |
+
- [Demo](#demo)
|
41 |
+
- [Our Hyperparameters](#our-hyperparameters)
|
42 |
+
|
43 |
+
## License
|
44 |
+
|
45 |
+
The code is distributed under the CC BY-NC-SA 4.0 License.
|
46 |
+
See [LICENSE](LICENSE) for more information.
|
47 |
+
|
48 |
+
```python
|
49 |
+
# Copyright (C) 2024-present Naver Corporation. All rights reserved.
|
50 |
+
# Licensed under CC BY-NC-SA 4.0 (non-commercial use only).
|
51 |
+
```
|
52 |
+
|
53 |
+
## Get Started
|
54 |
+
|
55 |
+
### Installation
|
56 |
+
|
57 |
+
1. Clone DUSt3R.
|
58 |
+
```bash
|
59 |
+
git clone --recursive https://github.com/naver/dust3r
|
60 |
+
cd dust3r
|
61 |
+
# if you have already cloned dust3r:
|
62 |
+
# git submodule update --init --recursive
|
63 |
+
```
|
64 |
+
|
65 |
+
2. Create the environment, here we show an example using conda.
|
66 |
+
```bash
|
67 |
+
conda create -n dust3r python=3.11 cmake=3.14.0
|
68 |
+
conda activate dust3r
|
69 |
+
conda install pytorch torchvision pytorch-cuda=12.1 -c pytorch -c nvidia # use the correct version of cuda for your system
|
70 |
+
pip install -r requirements.txt
|
71 |
+
# Optional: you can also install additional packages to:
|
72 |
+
# - add support for HEIC images
|
73 |
+
# - add pyrender, used to render depthmap in some datasets preprocessing
|
74 |
+
# - add required packages for visloc.py
|
75 |
+
pip install -r requirements_optional.txt
|
76 |
+
```
|
77 |
+
|
78 |
+
3. Optional, compile the cuda kernels for RoPE (as in CroCo v2).
|
79 |
+
```bash
|
80 |
+
# DUST3R relies on RoPE positional embeddings for which you can compile some cuda kernels for faster runtime.
|
81 |
+
cd croco/models/curope/
|
82 |
+
python setup.py build_ext --inplace
|
83 |
+
cd ../../../
|
84 |
+
```
|
85 |
+
|
86 |
+
### Checkpoints
|
87 |
+
|
88 |
+
You can obtain the checkpoints by two ways:
|
89 |
+
|
90 |
+
1) You can use our huggingface_hub integration: the models will be downloaded automatically.
|
91 |
+
|
92 |
+
2) Otherwise, We provide several pre-trained models:
|
93 |
+
|
94 |
+
| Modelname | Training resolutions | Head | Encoder | Decoder |
|
95 |
+
|-------------|----------------------|------|---------|---------|
|
96 |
+
| [`DUSt3R_ViTLarge_BaseDecoder_224_linear.pth`](https://download.europe.naverlabs.com/ComputerVision/DUSt3R/DUSt3R_ViTLarge_BaseDecoder_224_linear.pth) | 224x224 | Linear | ViT-L | ViT-B |
|
97 |
+
| [`DUSt3R_ViTLarge_BaseDecoder_512_linear.pth`](https://download.europe.naverlabs.com/ComputerVision/DUSt3R/DUSt3R_ViTLarge_BaseDecoder_512_linear.pth) | 512x384, 512x336, 512x288, 512x256, 512x160 | Linear | ViT-L | ViT-B |
|
98 |
+
| [`DUSt3R_ViTLarge_BaseDecoder_512_dpt.pth`](https://download.europe.naverlabs.com/ComputerVision/DUSt3R/DUSt3R_ViTLarge_BaseDecoder_512_dpt.pth) | 512x384, 512x336, 512x288, 512x256, 512x160 | DPT | ViT-L | ViT-B |
|
99 |
+
|
100 |
+
You can check the hyperparameters we used to train these models in the [section: Our Hyperparameters](#our-hyperparameters)
|
101 |
+
|
102 |
+
To download a specific model, for example `DUSt3R_ViTLarge_BaseDecoder_512_dpt.pth`:
|
103 |
+
```bash
|
104 |
+
mkdir -p checkpoints/
|
105 |
+
wget https://download.europe.naverlabs.com/ComputerVision/DUSt3R/DUSt3R_ViTLarge_BaseDecoder_512_dpt.pth -P checkpoints/
|
106 |
+
```
|
107 |
+
|
108 |
+
For the checkpoints, make sure to agree to the license of all the public training datasets and base checkpoints we used, in addition to CC-BY-NC-SA 4.0. Again, see [section: Our Hyperparameters](#our-hyperparameters) for details.
|
109 |
+
|
110 |
+
### Interactive demo
|
111 |
+
|
112 |
+
In this demo, you should be able run DUSt3R on your machine to reconstruct a scene.
|
113 |
+
First select images that depicts the same scene.
|
114 |
+
|
115 |
+
You can adjust the global alignment schedule and its number of iterations.
|
116 |
+
|
117 |
+
> [!NOTE]
|
118 |
+
> If you selected one or two images, the global alignment procedure will be skipped (mode=GlobalAlignerMode.PairViewer)
|
119 |
+
|
120 |
+
Hit "Run" and wait.
|
121 |
+
When the global alignment ends, the reconstruction appears.
|
122 |
+
Use the slider "min_conf_thr" to show or remove low confidence areas.
|
123 |
+
|
124 |
+
```bash
|
125 |
+
python3 demo.py --model_name DUSt3R_ViTLarge_BaseDecoder_512_dpt
|
126 |
+
|
127 |
+
# Use --weights to load a checkpoint from a local file, eg --weights checkpoints/DUSt3R_ViTLarge_BaseDecoder_512_dpt.pth
|
128 |
+
# Use --image_size to select the correct resolution for the selected checkpoint. 512 (default) or 224
|
129 |
+
# Use --local_network to make it accessible on the local network, or --server_name to specify the url manually
|
130 |
+
# Use --server_port to change the port, by default it will search for an available port starting at 7860
|
131 |
+
# Use --device to use a different device, by default it's "cuda"
|
132 |
+
```
|
133 |
+
|
134 |
+
### Interactive demo with docker
|
135 |
+
|
136 |
+
To run DUSt3R using Docker, including with NVIDIA CUDA support, follow these instructions:
|
137 |
+
|
138 |
+
1. **Install Docker**: If not already installed, download and install `docker` and `docker compose` from the [Docker website](https://www.docker.com/get-started).
|
139 |
+
|
140 |
+
2. **Install NVIDIA Docker Toolkit**: For GPU support, install the NVIDIA Docker toolkit from the [Nvidia website](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html).
|
141 |
+
|
142 |
+
3. **Build the Docker image and run it**: `cd` into the `./docker` directory and run the following commands:
|
143 |
+
|
144 |
+
```bash
|
145 |
+
cd docker
|
146 |
+
bash run.sh --with-cuda --model_name="DUSt3R_ViTLarge_BaseDecoder_512_dpt"
|
147 |
+
```
|
148 |
+
|
149 |
+
Or if you want to run the demo without CUDA support, run the following command:
|
150 |
+
|
151 |
+
```bash
|
152 |
+
cd docker
|
153 |
+
bash run.sh --model_name="DUSt3R_ViTLarge_BaseDecoder_512_dpt"
|
154 |
+
```
|
155 |
+
|
156 |
+
By default, `demo.py` is lanched with the option `--local_network`.
|
157 |
+
Visit `http://localhost:7860/` to access the web UI (or replace `localhost` with the machine's name to access it from the network).
|
158 |
+
|
159 |
+
`run.sh` will launch docker-compose using either the [docker-compose-cuda.yml](docker/docker-compose-cuda.yml) or [docker-compose-cpu.ym](docker/docker-compose-cpu.yml) config file, then it starts the demo using [entrypoint.sh](docker/files/entrypoint.sh).
|
160 |
+
|
161 |
+
|
162 |
+
![demo](assets/demo.jpg)
|
163 |
+
|
164 |
+
## Usage
|
165 |
+
|
166 |
+
```python
|
167 |
+
from dust3r.inference import inference
|
168 |
+
from dust3r.model import AsymmetricCroCo3DStereo
|
169 |
+
from dust3r.utils.image import load_images
|
170 |
+
from dust3r.image_pairs import make_pairs
|
171 |
+
from dust3r.cloud_opt import global_aligner, GlobalAlignerMode
|
172 |
+
|
173 |
+
if __name__ == '__main__':
|
174 |
+
device = 'cuda'
|
175 |
+
batch_size = 1
|
176 |
+
schedule = 'cosine'
|
177 |
+
lr = 0.01
|
178 |
+
niter = 300
|
179 |
+
|
180 |
+
model_name = "naver/DUSt3R_ViTLarge_BaseDecoder_512_dpt"
|
181 |
+
# you can put the path to a local checkpoint in model_name if needed
|
182 |
+
model = AsymmetricCroCo3DStereo.from_pretrained(model_name).to(device)
|
183 |
+
# load_images can take a list of images or a directory
|
184 |
+
images = load_images(['croco/assets/Chateau1.png', 'croco/assets/Chateau2.png'], size=512)
|
185 |
+
pairs = make_pairs(images, scene_graph='complete', prefilter=None, symmetrize=True)
|
186 |
+
output = inference(pairs, model, device, batch_size=batch_size)
|
187 |
+
|
188 |
+
# at this stage, you have the raw dust3r predictions
|
189 |
+
view1, pred1 = output['view1'], output['pred1']
|
190 |
+
view2, pred2 = output['view2'], output['pred2']
|
191 |
+
# here, view1, pred1, view2, pred2 are dicts of lists of len(2)
|
192 |
+
# -> because we symmetrize we have (im1, im2) and (im2, im1) pairs
|
193 |
+
# in each view you have:
|
194 |
+
# an integer image identifier: view1['idx'] and view2['idx']
|
195 |
+
# the img: view1['img'] and view2['img']
|
196 |
+
# the image shape: view1['true_shape'] and view2['true_shape']
|
197 |
+
# an instance string output by the dataloader: view1['instance'] and view2['instance']
|
198 |
+
# pred1 and pred2 contains the confidence values: pred1['conf'] and pred2['conf']
|
199 |
+
# pred1 contains 3D points for view1['img'] in view1['img'] space: pred1['pts3d']
|
200 |
+
# pred2 contains 3D points for view2['img'] in view1['img'] space: pred2['pts3d_in_other_view']
|
201 |
+
|
202 |
+
# next we'll use the global_aligner to align the predictions
|
203 |
+
# depending on your task, you may be fine with the raw output and not need it
|
204 |
+
# with only two input images, you could use GlobalAlignerMode.PairViewer: it would just convert the output
|
205 |
+
# if using GlobalAlignerMode.PairViewer, no need to run compute_global_alignment
|
206 |
+
scene = global_aligner(output, device=device, mode=GlobalAlignerMode.PointCloudOptimizer)
|
207 |
+
loss = scene.compute_global_alignment(init="mst", niter=niter, schedule=schedule, lr=lr)
|
208 |
+
|
209 |
+
# retrieve useful values from scene:
|
210 |
+
imgs = scene.imgs
|
211 |
+
focals = scene.get_focals()
|
212 |
+
poses = scene.get_im_poses()
|
213 |
+
pts3d = scene.get_pts3d()
|
214 |
+
confidence_masks = scene.get_masks()
|
215 |
+
|
216 |
+
# visualize reconstruction
|
217 |
+
scene.show()
|
218 |
+
|
219 |
+
# find 2D-2D matches between the two images
|
220 |
+
from dust3r.utils.geometry import find_reciprocal_matches, xy_grid
|
221 |
+
pts2d_list, pts3d_list = [], []
|
222 |
+
for i in range(2):
|
223 |
+
conf_i = confidence_masks[i].cpu().numpy()
|
224 |
+
pts2d_list.append(xy_grid(*imgs[i].shape[:2][::-1])[conf_i]) # imgs[i].shape[:2] = (H, W)
|
225 |
+
pts3d_list.append(pts3d[i].detach().cpu().numpy()[conf_i])
|
226 |
+
reciprocal_in_P2, nn2_in_P1, num_matches = find_reciprocal_matches(*pts3d_list)
|
227 |
+
print(f'found {num_matches} matches')
|
228 |
+
matches_im1 = pts2d_list[1][reciprocal_in_P2]
|
229 |
+
matches_im0 = pts2d_list[0][nn2_in_P1][reciprocal_in_P2]
|
230 |
+
|
231 |
+
# visualize a few matches
|
232 |
+
import numpy as np
|
233 |
+
from matplotlib import pyplot as pl
|
234 |
+
n_viz = 10
|
235 |
+
match_idx_to_viz = np.round(np.linspace(0, num_matches-1, n_viz)).astype(int)
|
236 |
+
viz_matches_im0, viz_matches_im1 = matches_im0[match_idx_to_viz], matches_im1[match_idx_to_viz]
|
237 |
+
|
238 |
+
H0, W0, H1, W1 = *imgs[0].shape[:2], *imgs[1].shape[:2]
|
239 |
+
img0 = np.pad(imgs[0], ((0, max(H1 - H0, 0)), (0, 0), (0, 0)), 'constant', constant_values=0)
|
240 |
+
img1 = np.pad(imgs[1], ((0, max(H0 - H1, 0)), (0, 0), (0, 0)), 'constant', constant_values=0)
|
241 |
+
img = np.concatenate((img0, img1), axis=1)
|
242 |
+
pl.figure()
|
243 |
+
pl.imshow(img)
|
244 |
+
cmap = pl.get_cmap('jet')
|
245 |
+
for i in range(n_viz):
|
246 |
+
(x0, y0), (x1, y1) = viz_matches_im0[i].T, viz_matches_im1[i].T
|
247 |
+
pl.plot([x0, x1 + W0], [y0, y1], '-+', color=cmap(i / (n_viz - 1)), scalex=False, scaley=False)
|
248 |
+
pl.show(block=True)
|
249 |
+
|
250 |
+
```
|
251 |
+
![matching example on croco pair](assets/matching.jpg)
|
252 |
+
|
253 |
+
## Training
|
254 |
+
|
255 |
+
In this section, we present a short demonstration to get started with training DUSt3R.
|
256 |
+
|
257 |
+
### Datasets
|
258 |
+
At this moment, we have added the following training datasets:
|
259 |
+
- [CO3Dv2](https://github.com/facebookresearch/co3d) - [Creative Commons Attribution-NonCommercial 4.0 International](https://github.com/facebookresearch/co3d/blob/main/LICENSE)
|
260 |
+
- [ARKitScenes](https://github.com/apple/ARKitScenes) - [Creative Commons Attribution-NonCommercial-ShareAlike 4.0](https://github.com/apple/ARKitScenes/tree/main?tab=readme-ov-file#license)
|
261 |
+
- [ScanNet++](https://kaldir.vc.in.tum.de/scannetpp/) - [non-commercial research and educational purposes](https://kaldir.vc.in.tum.de/scannetpp/static/scannetpp-terms-of-use.pdf)
|
262 |
+
- [BlendedMVS](https://github.com/YoYo000/BlendedMVS) - [Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/)
|
263 |
+
- [WayMo Open dataset](https://github.com/waymo-research/waymo-open-dataset) - [Non-Commercial Use](https://waymo.com/open/terms/)
|
264 |
+
- [Habitat-Sim](https://github.com/facebookresearch/habitat-sim/blob/main/DATASETS.md)
|
265 |
+
- [MegaDepth](https://www.cs.cornell.edu/projects/megadepth/)
|
266 |
+
- [StaticThings3D](https://github.com/lmb-freiburg/robustmvd/blob/master/rmvd/data/README.md#staticthings3d)
|
267 |
+
- [WildRGB-D](https://github.com/wildrgbd/wildrgbd/)
|
268 |
+
|
269 |
+
For each dataset, we provide a preprocessing script in the `datasets_preprocess` directory and an archive containing the list of pairs when needed.
|
270 |
+
You have to download the datasets yourself from their official sources, agree to their license, download our list of pairs, and run the preprocessing script.
|
271 |
+
|
272 |
+
Links:
|
273 |
+
|
274 |
+
[ARKitScenes pairs](https://download.europe.naverlabs.com/ComputerVision/DUSt3R/arkitscenes_pairs.zip)
|
275 |
+
[ScanNet++ pairs](https://download.europe.naverlabs.com/ComputerVision/DUSt3R/scannetpp_pairs.zip)
|
276 |
+
[BlendedMVS pairs](https://download.europe.naverlabs.com/ComputerVision/DUSt3R/blendedmvs_pairs.npy)
|
277 |
+
[WayMo Open dataset pairs](https://download.europe.naverlabs.com/ComputerVision/DUSt3R/waymo_pairs.npz)
|
278 |
+
[Habitat metadata](https://download.europe.naverlabs.com/ComputerVision/DUSt3R/habitat_5views_v1_512x512_metadata.tar.gz)
|
279 |
+
[MegaDepth pairs](https://download.europe.naverlabs.com/ComputerVision/DUSt3R/megadepth_pairs.npz)
|
280 |
+
[StaticThings3D pairs](https://download.europe.naverlabs.com/ComputerVision/DUSt3R/staticthings_pairs.npy)
|
281 |
+
|
282 |
+
> [!NOTE]
|
283 |
+
> They are not strictly equivalent to what was used to train DUSt3R, but they should be close enough.
|
284 |
+
|
285 |
+
### Demo
|
286 |
+
For this training demo, we're going to download and prepare a subset of [CO3Dv2](https://github.com/facebookresearch/co3d) - [Creative Commons Attribution-NonCommercial 4.0 International](https://github.com/facebookresearch/co3d/blob/main/LICENSE) and launch the training code on it.
|
287 |
+
The demo model will be trained for a few epochs on a very small dataset.
|
288 |
+
It will not be very good.
|
289 |
+
|
290 |
+
```bash
|
291 |
+
# download and prepare the co3d subset
|
292 |
+
mkdir -p data/co3d_subset
|
293 |
+
cd data/co3d_subset
|
294 |
+
git clone https://github.com/facebookresearch/co3d
|
295 |
+
cd co3d
|
296 |
+
python3 ./co3d/download_dataset.py --download_folder ../ --single_sequence_subset
|
297 |
+
rm ../*.zip
|
298 |
+
cd ../../..
|
299 |
+
|
300 |
+
python3 datasets_preprocess/preprocess_co3d.py --co3d_dir data/co3d_subset --output_dir data/co3d_subset_processed --single_sequence_subset
|
301 |
+
|
302 |
+
# download the pretrained croco v2 checkpoint
|
303 |
+
mkdir -p checkpoints/
|
304 |
+
wget https://download.europe.naverlabs.com/ComputerVision/CroCo/CroCo_V2_ViTLarge_BaseDecoder.pth -P checkpoints/
|
305 |
+
|
306 |
+
# the training of dust3r is done in 3 steps.
|
307 |
+
# for this example we'll do fewer epochs, for the actual hyperparameters we used in the paper, see the next section: "Our Hyperparameters"
|
308 |
+
# step 1 - train dust3r for 224 resolution
|
309 |
+
torchrun --nproc_per_node=4 train.py \
|
310 |
+
--train_dataset "1000 @ Co3d(split='train', ROOT='data/co3d_subset_processed', aug_crop=16, mask_bg='rand', resolution=224, transform=ColorJitter)" \
|
311 |
+
--test_dataset "100 @ Co3d(split='test', ROOT='data/co3d_subset_processed', resolution=224, seed=777)" \
|
312 |
+
--model "AsymmetricCroCo3DStereo(pos_embed='RoPE100', img_size=(224, 224), head_type='linear', output_mode='pts3d', depth_mode=('exp', -inf, inf), conf_mode=('exp', 1, inf), enc_embed_dim=1024, enc_depth=24, enc_num_heads=16, dec_embed_dim=768, dec_depth=12, dec_num_heads=12)" \
|
313 |
+
--train_criterion "ConfLoss(Regr3D(L21, norm_mode='avg_dis'), alpha=0.2)" \
|
314 |
+
--test_criterion "Regr3D_ScaleShiftInv(L21, gt_scale=True)" \
|
315 |
+
--pretrained "checkpoints/CroCo_V2_ViTLarge_BaseDecoder.pth" \
|
316 |
+
--lr 0.0001 --min_lr 1e-06 --warmup_epochs 1 --epochs 10 --batch_size 16 --accum_iter 1 \
|
317 |
+
--save_freq 1 --keep_freq 5 --eval_freq 1 \
|
318 |
+
--output_dir "checkpoints/dust3r_demo_224"
|
319 |
+
|
320 |
+
# step 2 - train dust3r for 512 resolution
|
321 |
+
torchrun --nproc_per_node=4 train.py \
|
322 |
+
--train_dataset "1000 @ Co3d(split='train', ROOT='data/co3d_subset_processed', aug_crop=16, mask_bg='rand', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter)" \
|
323 |
+
--test_dataset "100 @ Co3d(split='test', ROOT='data/co3d_subset_processed', resolution=(512,384), seed=777)" \
|
324 |
+
--model "AsymmetricCroCo3DStereo(pos_embed='RoPE100', patch_embed_cls='ManyAR_PatchEmbed', img_size=(512, 512), head_type='linear', output_mode='pts3d', depth_mode=('exp', -inf, inf), conf_mode=('exp', 1, inf), enc_embed_dim=1024, enc_depth=24, enc_num_heads=16, dec_embed_dim=768, dec_depth=12, dec_num_heads=12)" \
|
325 |
+
--train_criterion "ConfLoss(Regr3D(L21, norm_mode='avg_dis'), alpha=0.2)" \
|
326 |
+
--test_criterion "Regr3D_ScaleShiftInv(L21, gt_scale=True)" \
|
327 |
+
--pretrained "checkpoints/dust3r_demo_224/checkpoint-best.pth" \
|
328 |
+
--lr 0.0001 --min_lr 1e-06 --warmup_epochs 1 --epochs 10 --batch_size 4 --accum_iter 4 \
|
329 |
+
--save_freq 1 --keep_freq 5 --eval_freq 1 \
|
330 |
+
--output_dir "checkpoints/dust3r_demo_512"
|
331 |
+
|
332 |
+
# step 3 - train dust3r for 512 resolution with dpt
|
333 |
+
torchrun --nproc_per_node=4 train.py \
|
334 |
+
--train_dataset "1000 @ Co3d(split='train', ROOT='data/co3d_subset_processed', aug_crop=16, mask_bg='rand', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter)" \
|
335 |
+
--test_dataset "100 @ Co3d(split='test', ROOT='data/co3d_subset_processed', resolution=(512,384), seed=777)" \
|
336 |
+
--model "AsymmetricCroCo3DStereo(pos_embed='RoPE100', patch_embed_cls='ManyAR_PatchEmbed', img_size=(512, 512), head_type='dpt', output_mode='pts3d', depth_mode=('exp', -inf, inf), conf_mode=('exp', 1, inf), enc_embed_dim=1024, enc_depth=24, enc_num_heads=16, dec_embed_dim=768, dec_depth=12, dec_num_heads=12)" \
|
337 |
+
--train_criterion "ConfLoss(Regr3D(L21, norm_mode='avg_dis'), alpha=0.2)" \
|
338 |
+
--test_criterion "Regr3D_ScaleShiftInv(L21, gt_scale=True)" \
|
339 |
+
--pretrained "checkpoints/dust3r_demo_512/checkpoint-best.pth" \
|
340 |
+
--lr 0.0001 --min_lr 1e-06 --warmup_epochs 1 --epochs 10 --batch_size 2 --accum_iter 8 \
|
341 |
+
--save_freq 1 --keep_freq 5 --eval_freq 1 \
|
342 |
+
--output_dir "checkpoints/dust3r_demo_512dpt"
|
343 |
+
|
344 |
+
```
|
345 |
+
|
346 |
+
### Our Hyperparameters
|
347 |
+
|
348 |
+
Here are the commands we used for training the models:
|
349 |
+
|
350 |
+
```bash
|
351 |
+
# NOTE: ROOT path omitted for datasets
|
352 |
+
# 224 linear
|
353 |
+
torchrun --nproc_per_node 8 train.py \
|
354 |
+
--train_dataset=" + 100_000 @ Habitat(1_000_000, split='train', aug_crop=16, resolution=224, transform=ColorJitter) + 100_000 @ BlendedMVS(split='train', aug_crop=16, resolution=224, transform=ColorJitter) + 100_000 @ MegaDepth(split='train', aug_crop=16, resolution=224, transform=ColorJitter) + 100_000 @ ARKitScenes(aug_crop=256, resolution=224, transform=ColorJitter) + 100_000 @ Co3d(split='train', aug_crop=16, mask_bg='rand', resolution=224, transform=ColorJitter) + 100_000 @ StaticThings3D(aug_crop=256, mask_bg='rand', resolution=224, transform=ColorJitter) + 100_000 @ ScanNetpp(split='train', aug_crop=256, resolution=224, transform=ColorJitter) + 100_000 @ InternalUnreleasedDataset(aug_crop=128, resolution=224, transform=ColorJitter) " \
|
355 |
+
--test_dataset=" Habitat(1_000, split='val', resolution=224, seed=777) + 1_000 @ BlendedMVS(split='val', resolution=224, seed=777) + 1_000 @ MegaDepth(split='val', resolution=224, seed=777) + 1_000 @ Co3d(split='test', mask_bg='rand', resolution=224, seed=777) " \
|
356 |
+
--train_criterion="ConfLoss(Regr3D(L21, norm_mode='avg_dis'), alpha=0.2)" \
|
357 |
+
--test_criterion="Regr3D_ScaleShiftInv(L21, gt_scale=True)" \
|
358 |
+
--model="AsymmetricCroCo3DStereo(pos_embed='RoPE100', img_size=(224, 224), head_type='linear', output_mode='pts3d', depth_mode=('exp', -inf, inf), conf_mode=('exp', 1, inf), enc_embed_dim=1024, enc_depth=24, enc_num_heads=16, dec_embed_dim=768, dec_depth=12, dec_num_heads=12)" \
|
359 |
+
--pretrained="checkpoints/CroCo_V2_ViTLarge_BaseDecoder.pth" \
|
360 |
+
--lr=0.0001 --min_lr=1e-06 --warmup_epochs=10 --epochs=100 --batch_size=16 --accum_iter=1 \
|
361 |
+
--save_freq=5 --keep_freq=10 --eval_freq=1 \
|
362 |
+
--output_dir="checkpoints/dust3r_224"
|
363 |
+
|
364 |
+
# 512 linear
|
365 |
+
torchrun --nproc_per_node 8 train.py \
|
366 |
+
--train_dataset=" + 10_000 @ Habitat(1_000_000, split='train', aug_crop=16, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ BlendedMVS(split='train', aug_crop=16, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ MegaDepth(split='train', aug_crop=16, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ ARKitScenes(aug_crop=256, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ Co3d(split='train', aug_crop=16, mask_bg='rand', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ StaticThings3D(aug_crop=256, mask_bg='rand', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ ScanNetpp(split='train', aug_crop=256, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ InternalUnreleasedDataset(aug_crop=128, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) " \
|
367 |
+
--test_dataset=" Habitat(1_000, split='val', resolution=(512,384), seed=777) + 1_000 @ BlendedMVS(split='val', resolution=(512,384), seed=777) + 1_000 @ MegaDepth(split='val', resolution=(512,336), seed=777) + 1_000 @ Co3d(split='test', resolution=(512,384), seed=777) " \
|
368 |
+
--train_criterion="ConfLoss(Regr3D(L21, norm_mode='avg_dis'), alpha=0.2)" \
|
369 |
+
--test_criterion="Regr3D_ScaleShiftInv(L21, gt_scale=True)" \
|
370 |
+
--model="AsymmetricCroCo3DStereo(pos_embed='RoPE100', patch_embed_cls='ManyAR_PatchEmbed', img_size=(512, 512), head_type='linear', output_mode='pts3d', depth_mode=('exp', -inf, inf), conf_mode=('exp', 1, inf), enc_embed_dim=1024, enc_depth=24, enc_num_heads=16, dec_embed_dim=768, dec_depth=12, dec_num_heads=12)" \
|
371 |
+
--pretrained="checkpoints/dust3r_224/checkpoint-best.pth" \
|
372 |
+
--lr=0.0001 --min_lr=1e-06 --warmup_epochs=20 --epochs=100 --batch_size=4 --accum_iter=2 \
|
373 |
+
--save_freq=10 --keep_freq=10 --eval_freq=1 --print_freq=10 \
|
374 |
+
--output_dir="checkpoints/dust3r_512"
|
375 |
+
|
376 |
+
# 512 dpt
|
377 |
+
torchrun --nproc_per_node 8 train.py \
|
378 |
+
--train_dataset=" + 10_000 @ Habitat(1_000_000, split='train', aug_crop=16, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ BlendedMVS(split='train', aug_crop=16, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ MegaDepth(split='train', aug_crop=16, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ ARKitScenes(aug_crop=256, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ Co3d(split='train', aug_crop=16, mask_bg='rand', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ StaticThings3D(aug_crop=256, mask_bg='rand', resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ ScanNetpp(split='train', aug_crop=256, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) + 10_000 @ InternalUnreleasedDataset(aug_crop=128, resolution=[(512, 384), (512, 336), (512, 288), (512, 256), (512, 160)], transform=ColorJitter) " \
|
379 |
+
--test_dataset=" Habitat(1_000, split='val', resolution=(512,384), seed=777) + 1_000 @ BlendedMVS(split='val', resolution=(512,384), seed=777) + 1_000 @ MegaDepth(split='val', resolution=(512,336), seed=777) + 1_000 @ Co3d(split='test', resolution=(512,384), seed=777) " \
|
380 |
+
--train_criterion="ConfLoss(Regr3D(L21, norm_mode='avg_dis'), alpha=0.2)" \
|
381 |
+
--test_criterion="Regr3D_ScaleShiftInv(L21, gt_scale=True)" \
|
382 |
+
--model="AsymmetricCroCo3DStereo(pos_embed='RoPE100', patch_embed_cls='ManyAR_PatchEmbed', img_size=(512, 512), head_type='dpt', output_mode='pts3d', depth_mode=('exp', -inf, inf), conf_mode=('exp', 1, inf), enc_embed_dim=1024, enc_depth=24, enc_num_heads=16, dec_embed_dim=768, dec_depth=12, dec_num_heads=12)" \
|
383 |
+
--pretrained="checkpoints/dust3r_512/checkpoint-best.pth" \
|
384 |
+
--lr=0.0001 --min_lr=1e-06 --warmup_epochs=15 --epochs=90 --batch_size=4 --accum_iter=2 \
|
385 |
+
--save_freq=5 --keep_freq=10 --eval_freq=1 --print_freq=10 \
|
386 |
+
--output_dir="checkpoints/dust3r_512dpt"
|
387 |
+
|
388 |
+
```
|
third_party/mast3r/dust3r/assets/demo.jpg
ADDED
Git LFS Details
|
third_party/mast3r/dust3r/assets/dust3r.jpg
ADDED
Git LFS Details
|
third_party/mast3r/dust3r/assets/dust3r_archi.jpg
ADDED
Git LFS Details
|
third_party/mast3r/dust3r/assets/matching.jpg
ADDED
Git LFS Details
|
third_party/mast3r/dust3r/assets/pipeline1.jpg
ADDED
Git LFS Details
|
third_party/mast3r/dust3r/croco/LICENSE
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
CroCo, Copyright (c) 2022-present Naver Corporation, is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 license.
|
2 |
+
|
3 |
+
A summary of the CC BY-NC-SA 4.0 license is located here:
|
4 |
+
https://creativecommons.org/licenses/by-nc-sa/4.0/
|
5 |
+
|
6 |
+
The CC BY-NC-SA 4.0 license is located here:
|
7 |
+
https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
|
8 |
+
|
9 |
+
|
10 |
+
SEE NOTICE BELOW WITH RESPECT TO THE FILE: models/pos_embed.py, models/blocks.py
|
11 |
+
|
12 |
+
***************************
|
13 |
+
|
14 |
+
NOTICE WITH RESPECT TO THE FILE: models/pos_embed.py
|
15 |
+
|
16 |
+
This software is being redistributed in a modifiled form. The original form is available here:
|
17 |
+
|
18 |
+
https://github.com/facebookresearch/mae/blob/main/util/pos_embed.py
|
19 |
+
|
20 |
+
This software in this file incorporates parts of the following software available here:
|
21 |
+
|
22 |
+
Transformer: https://github.com/tensorflow/models/blob/master/official/legacy/transformer/model_utils.py
|
23 |
+
available under the following license: https://github.com/tensorflow/models/blob/master/LICENSE
|
24 |
+
|
25 |
+
MoCo v3: https://github.com/facebookresearch/moco-v3
|
26 |
+
available under the following license: https://github.com/facebookresearch/moco-v3/blob/main/LICENSE
|
27 |
+
|
28 |
+
DeiT: https://github.com/facebookresearch/deit
|
29 |
+
available under the following license: https://github.com/facebookresearch/deit/blob/main/LICENSE
|
30 |
+
|
31 |
+
|
32 |
+
ORIGINAL COPYRIGHT NOTICE AND PERMISSION NOTICE AVAILABLE HERE IS REPRODUCE BELOW:
|
33 |
+
|
34 |
+
https://github.com/facebookresearch/mae/blob/main/LICENSE
|
35 |
+
|
36 |
+
Attribution-NonCommercial 4.0 International
|
37 |
+
|
38 |
+
***************************
|
39 |
+
|
40 |
+
NOTICE WITH RESPECT TO THE FILE: models/blocks.py
|
41 |
+
|
42 |
+
This software is being redistributed in a modifiled form. The original form is available here:
|
43 |
+
|
44 |
+
https://github.com/rwightman/pytorch-image-models
|
45 |
+
|
46 |
+
ORIGINAL COPYRIGHT NOTICE AND PERMISSION NOTICE AVAILABLE HERE IS REPRODUCE BELOW:
|
47 |
+
|
48 |
+
https://github.com/rwightman/pytorch-image-models/blob/master/LICENSE
|
49 |
+
|
50 |
+
Apache License
|
51 |
+
Version 2.0, January 2004
|
52 |
+
http://www.apache.org/licenses/
|
third_party/mast3r/dust3r/croco/NOTICE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
CroCo
|
2 |
+
Copyright 2022-present NAVER Corp.
|
3 |
+
|
4 |
+
This project contains subcomponents with separate copyright notices and license terms.
|
5 |
+
Your use of the source code for these subcomponents is subject to the terms and conditions of the following licenses.
|
6 |
+
|
7 |
+
====
|
8 |
+
|
9 |
+
facebookresearch/mae
|
10 |
+
https://github.com/facebookresearch/mae
|
11 |
+
|
12 |
+
Attribution-NonCommercial 4.0 International
|
13 |
+
|
14 |
+
====
|
15 |
+
|
16 |
+
rwightman/pytorch-image-models
|
17 |
+
https://github.com/rwightman/pytorch-image-models
|
18 |
+
|
19 |
+
Apache License
|
20 |
+
Version 2.0, January 2004
|
21 |
+
http://www.apache.org/licenses/
|
third_party/mast3r/dust3r/croco/README.MD
ADDED
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# CroCo + CroCo v2 / CroCo-Stereo / CroCo-Flow
|
2 |
+
|
3 |
+
[[`CroCo arXiv`](https://arxiv.org/abs/2210.10716)] [[`CroCo v2 arXiv`](https://arxiv.org/abs/2211.10408)] [[`project page and demo`](https://croco.europe.naverlabs.com/)]
|
4 |
+
|
5 |
+
This repository contains the code for our CroCo model presented in our NeurIPS'22 paper [CroCo: Self-Supervised Pre-training for 3D Vision Tasks by Cross-View Completion](https://openreview.net/pdf?id=wZEfHUM5ri) and its follow-up extension published at ICCV'23 [Improved Cross-view Completion Pre-training for Stereo Matching and Optical Flow](https://openaccess.thecvf.com/content/ICCV2023/html/Weinzaepfel_CroCo_v2_Improved_Cross-view_Completion_Pre-training_for_Stereo_Matching_and_ICCV_2023_paper.html), refered to as CroCo v2:
|
6 |
+
|
7 |
+
![image](assets/arch.jpg)
|
8 |
+
|
9 |
+
```bibtex
|
10 |
+
@inproceedings{croco,
|
11 |
+
title={{CroCo: Self-Supervised Pre-training for 3D Vision Tasks by Cross-View Completion}},
|
12 |
+
author={{Weinzaepfel, Philippe and Leroy, Vincent and Lucas, Thomas and Br\'egier, Romain and Cabon, Yohann and Arora, Vaibhav and Antsfeld, Leonid and Chidlovskii, Boris and Csurka, Gabriela and Revaud J\'er\^ome}},
|
13 |
+
booktitle={{NeurIPS}},
|
14 |
+
year={2022}
|
15 |
+
}
|
16 |
+
|
17 |
+
@inproceedings{croco_v2,
|
18 |
+
title={{CroCo v2: Improved Cross-view Completion Pre-training for Stereo Matching and Optical Flow}},
|
19 |
+
author={Weinzaepfel, Philippe and Lucas, Thomas and Leroy, Vincent and Cabon, Yohann and Arora, Vaibhav and Br{\'e}gier, Romain and Csurka, Gabriela and Antsfeld, Leonid and Chidlovskii, Boris and Revaud, J{\'e}r{\^o}me},
|
20 |
+
booktitle={ICCV},
|
21 |
+
year={2023}
|
22 |
+
}
|
23 |
+
```
|
24 |
+
|
25 |
+
## License
|
26 |
+
|
27 |
+
The code is distributed under the CC BY-NC-SA 4.0 License. See [LICENSE](LICENSE) for more information.
|
28 |
+
Some components are based on code from [MAE](https://github.com/facebookresearch/mae) released under the CC BY-NC-SA 4.0 License and [timm](https://github.com/rwightman/pytorch-image-models) released under the Apache 2.0 License.
|
29 |
+
Some components for stereo matching and optical flow are based on code from [unimatch](https://github.com/autonomousvision/unimatch) released under the MIT license.
|
30 |
+
|
31 |
+
## Preparation
|
32 |
+
|
33 |
+
1. Install dependencies on a machine with a NVidia GPU using e.g. conda. Note that `habitat-sim` is required only for the interactive demo and the synthetic pre-training data generation. If you don't plan to use it, you can ignore the line installing it and use a more recent python version.
|
34 |
+
|
35 |
+
```bash
|
36 |
+
conda create -n croco python=3.7 cmake=3.14.0
|
37 |
+
conda activate croco
|
38 |
+
conda install habitat-sim headless -c conda-forge -c aihabitat
|
39 |
+
conda install pytorch torchvision -c pytorch
|
40 |
+
conda install notebook ipykernel matplotlib
|
41 |
+
conda install ipywidgets widgetsnbextension
|
42 |
+
conda install scikit-learn tqdm quaternion opencv # only for pretraining / habitat data generation
|
43 |
+
|
44 |
+
```
|
45 |
+
|
46 |
+
2. Compile cuda kernels for RoPE
|
47 |
+
|
48 |
+
CroCo v2 relies on RoPE positional embeddings for which you need to compile some cuda kernels.
|
49 |
+
```bash
|
50 |
+
cd models/curope/
|
51 |
+
python setup.py build_ext --inplace
|
52 |
+
cd ../../
|
53 |
+
```
|
54 |
+
|
55 |
+
This can be a bit long as we compile for all cuda architectures, feel free to update L9 of `models/curope/setup.py` to compile for specific architectures only.
|
56 |
+
You might also need to set the environment `CUDA_HOME` in case you use a custom cuda installation.
|
57 |
+
|
58 |
+
In case you cannot provide, we also provide a slow pytorch version, which will be automatically loaded.
|
59 |
+
|
60 |
+
3. Download pre-trained model
|
61 |
+
|
62 |
+
We provide several pre-trained models:
|
63 |
+
|
64 |
+
| modelname | pre-training data | pos. embed. | Encoder | Decoder |
|
65 |
+
|------------------------------------------------------------------------------------------------------------------------------------|-------------------|-------------|---------|---------|
|
66 |
+
| [`CroCo.pth`](https://download.europe.naverlabs.com/ComputerVision/CroCo/CroCo.pth) | Habitat | cosine | ViT-B | Small |
|
67 |
+
| [`CroCo_V2_ViTBase_SmallDecoder.pth`](https://download.europe.naverlabs.com/ComputerVision/CroCo/CroCo_V2_ViTBase_SmallDecoder.pth) | Habitat + real | RoPE | ViT-B | Small |
|
68 |
+
| [`CroCo_V2_ViTBase_BaseDecoder.pth`](https://download.europe.naverlabs.com/ComputerVision/CroCo/CroCo_V2_ViTBase_BaseDecoder.pth) | Habitat + real | RoPE | ViT-B | Base |
|
69 |
+
| [`CroCo_V2_ViTLarge_BaseDecoder.pth`](https://download.europe.naverlabs.com/ComputerVision/CroCo/CroCo_V2_ViTLarge_BaseDecoder.pth) | Habitat + real | RoPE | ViT-L | Base |
|
70 |
+
|
71 |
+
To download a specific model, i.e., the first one (`CroCo.pth`)
|
72 |
+
```bash
|
73 |
+
mkdir -p pretrained_models/
|
74 |
+
wget https://download.europe.naverlabs.com/ComputerVision/CroCo/CroCo.pth -P pretrained_models/
|
75 |
+
```
|
76 |
+
|
77 |
+
## Reconstruction example
|
78 |
+
|
79 |
+
Simply run after downloading the `CroCo_V2_ViTLarge_BaseDecoder` pretrained model (or update the corresponding line in `demo.py`)
|
80 |
+
```bash
|
81 |
+
python demo.py
|
82 |
+
```
|
83 |
+
|
84 |
+
## Interactive demonstration of cross-view completion reconstruction on the Habitat simulator
|
85 |
+
|
86 |
+
First download the test scene from Habitat:
|
87 |
+
```bash
|
88 |
+
python -m habitat_sim.utils.datasets_download --uids habitat_test_scenes --data-path habitat-sim-data/
|
89 |
+
```
|
90 |
+
|
91 |
+
Then, run the Notebook demo `interactive_demo.ipynb`.
|
92 |
+
|
93 |
+
In this demo, you should be able to sample a random reference viewpoint from an [Habitat](https://github.com/facebookresearch/habitat-sim) test scene. Use the sliders to change viewpoint and select a masked target view to reconstruct using CroCo.
|
94 |
+
![croco_interactive_demo](https://user-images.githubusercontent.com/1822210/200516576-7937bc6a-55f8-49ed-8618-3ddf89433ea4.jpg)
|
95 |
+
|
96 |
+
## Pre-training
|
97 |
+
|
98 |
+
### CroCo
|
99 |
+
|
100 |
+
To pre-train CroCo, please first generate the pre-training data from the Habitat simulator, following the instructions in [datasets/habitat_sim/README.MD](datasets/habitat_sim/README.MD) and then run the following command:
|
101 |
+
```
|
102 |
+
torchrun --nproc_per_node=4 pretrain.py --output_dir ./output/pretraining/
|
103 |
+
```
|
104 |
+
|
105 |
+
Our CroCo pre-training was launched on a single server with 4 GPUs.
|
106 |
+
It should take around 10 days with A100 or 15 days with V100 to do the 400 pre-training epochs, but decent performances are obtained earlier in training.
|
107 |
+
Note that, while the code contains the same scaling rule of the learning rate as MAE when changing the effective batch size, we did not experimented if it is valid in our case.
|
108 |
+
The first run can take a few minutes to start, to parse all available pre-training pairs.
|
109 |
+
|
110 |
+
### CroCo v2
|
111 |
+
|
112 |
+
For CroCo v2 pre-training, in addition to the generation of the pre-training data from the Habitat simulator above, please pre-extract the crops from the real datasets following the instructions in [datasets/crops/README.MD](datasets/crops/README.MD).
|
113 |
+
Then, run the following command for the largest model (ViT-L encoder, Base decoder):
|
114 |
+
```
|
115 |
+
torchrun --nproc_per_node=8 pretrain.py --model "CroCoNet(enc_embed_dim=1024, enc_depth=24, enc_num_heads=16, dec_embed_dim=768, dec_num_heads=12, dec_depth=12, pos_embed='RoPE100')" --dataset "habitat_release+ARKitScenes+MegaDepth+3DStreetView+IndoorVL" --warmup_epochs 12 --max_epoch 125 --epochs 250 --amp 0 --keep_freq 5 --output_dir ./output/pretraining_crocov2/
|
116 |
+
```
|
117 |
+
|
118 |
+
Our CroCo v2 pre-training was launched on a single server with 8 GPUs for the largest model, and on a single server with 4 GPUs for the smaller ones, keeping a batch size of 64 per gpu in all cases.
|
119 |
+
The largest model should take around 12 days on A100.
|
120 |
+
Note that, while the code contains the same scaling rule of the learning rate as MAE when changing the effective batch size, we did not experimented if it is valid in our case.
|
121 |
+
|
122 |
+
## Stereo matching and Optical flow downstream tasks
|
123 |
+
|
124 |
+
For CroCo-Stereo and CroCo-Flow, please refer to [stereoflow/README.MD](stereoflow/README.MD).
|
third_party/mast3r/dust3r/croco/assets/Chateau1.png
ADDED
Git LFS Details
|
third_party/mast3r/dust3r/croco/assets/Chateau2.png
ADDED
Git LFS Details
|
third_party/mast3r/dust3r/croco/assets/arch.jpg
ADDED
Git LFS Details
|
third_party/mast3r/dust3r/croco/croco-stereo-flow-demo.ipynb
ADDED
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "markdown",
|
5 |
+
"id": "9bca0f41",
|
6 |
+
"metadata": {},
|
7 |
+
"source": [
|
8 |
+
"# Simple inference example with CroCo-Stereo or CroCo-Flow"
|
9 |
+
]
|
10 |
+
},
|
11 |
+
{
|
12 |
+
"cell_type": "code",
|
13 |
+
"execution_count": null,
|
14 |
+
"id": "80653ef7",
|
15 |
+
"metadata": {},
|
16 |
+
"outputs": [],
|
17 |
+
"source": [
|
18 |
+
"# Copyright (C) 2022-present Naver Corporation. All rights reserved.\n",
|
19 |
+
"# Licensed under CC BY-NC-SA 4.0 (non-commercial use only)."
|
20 |
+
]
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"cell_type": "markdown",
|
24 |
+
"id": "4f033862",
|
25 |
+
"metadata": {},
|
26 |
+
"source": [
|
27 |
+
"First download the model(s) of your choice by running\n",
|
28 |
+
"```\n",
|
29 |
+
"bash stereoflow/download_model.sh crocostereo.pth\n",
|
30 |
+
"bash stereoflow/download_model.sh crocoflow.pth\n",
|
31 |
+
"```"
|
32 |
+
]
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"cell_type": "code",
|
36 |
+
"execution_count": null,
|
37 |
+
"id": "1fb2e392",
|
38 |
+
"metadata": {},
|
39 |
+
"outputs": [],
|
40 |
+
"source": [
|
41 |
+
"import torch\n",
|
42 |
+
"use_gpu = torch.cuda.is_available() and torch.cuda.device_count()>0\n",
|
43 |
+
"device = torch.device('cuda:0' if use_gpu else 'cpu')\n",
|
44 |
+
"import matplotlib.pylab as plt"
|
45 |
+
]
|
46 |
+
},
|
47 |
+
{
|
48 |
+
"cell_type": "code",
|
49 |
+
"execution_count": null,
|
50 |
+
"id": "e0e25d77",
|
51 |
+
"metadata": {},
|
52 |
+
"outputs": [],
|
53 |
+
"source": [
|
54 |
+
"from stereoflow.test import _load_model_and_criterion\n",
|
55 |
+
"from stereoflow.engine import tiled_pred\n",
|
56 |
+
"from stereoflow.datasets_stereo import img_to_tensor, vis_disparity\n",
|
57 |
+
"from stereoflow.datasets_flow import flowToColor\n",
|
58 |
+
"tile_overlap=0.7 # recommended value, higher value can be slightly better but slower"
|
59 |
+
]
|
60 |
+
},
|
61 |
+
{
|
62 |
+
"cell_type": "markdown",
|
63 |
+
"id": "86a921f5",
|
64 |
+
"metadata": {},
|
65 |
+
"source": [
|
66 |
+
"### CroCo-Stereo example"
|
67 |
+
]
|
68 |
+
},
|
69 |
+
{
|
70 |
+
"cell_type": "code",
|
71 |
+
"execution_count": null,
|
72 |
+
"id": "64e483cb",
|
73 |
+
"metadata": {},
|
74 |
+
"outputs": [],
|
75 |
+
"source": [
|
76 |
+
"image1 = np.asarray(Image.open('<path_to_left_image>'))\n",
|
77 |
+
"image2 = np.asarray(Image.open('<path_to_right_image>'))"
|
78 |
+
]
|
79 |
+
},
|
80 |
+
{
|
81 |
+
"cell_type": "code",
|
82 |
+
"execution_count": null,
|
83 |
+
"id": "f0d04303",
|
84 |
+
"metadata": {},
|
85 |
+
"outputs": [],
|
86 |
+
"source": [
|
87 |
+
"model, _, cropsize, with_conf, task, tile_conf_mode = _load_model_and_criterion('stereoflow_models/crocostereo.pth', None, device)\n"
|
88 |
+
]
|
89 |
+
},
|
90 |
+
{
|
91 |
+
"cell_type": "code",
|
92 |
+
"execution_count": null,
|
93 |
+
"id": "47dc14b5",
|
94 |
+
"metadata": {},
|
95 |
+
"outputs": [],
|
96 |
+
"source": [
|
97 |
+
"im1 = img_to_tensor(image1).to(device).unsqueeze(0)\n",
|
98 |
+
"im2 = img_to_tensor(image2).to(device).unsqueeze(0)\n",
|
99 |
+
"with torch.inference_mode():\n",
|
100 |
+
" pred, _, _ = tiled_pred(model, None, im1, im2, None, conf_mode=tile_conf_mode, overlap=tile_overlap, crop=cropsize, with_conf=with_conf, return_time=False)\n",
|
101 |
+
"pred = pred.squeeze(0).squeeze(0).cpu().numpy()"
|
102 |
+
]
|
103 |
+
},
|
104 |
+
{
|
105 |
+
"cell_type": "code",
|
106 |
+
"execution_count": null,
|
107 |
+
"id": "583b9f16",
|
108 |
+
"metadata": {},
|
109 |
+
"outputs": [],
|
110 |
+
"source": [
|
111 |
+
"plt.imshow(vis_disparity(pred))\n",
|
112 |
+
"plt.axis('off')"
|
113 |
+
]
|
114 |
+
},
|
115 |
+
{
|
116 |
+
"cell_type": "markdown",
|
117 |
+
"id": "d2df5d70",
|
118 |
+
"metadata": {},
|
119 |
+
"source": [
|
120 |
+
"### CroCo-Flow example"
|
121 |
+
]
|
122 |
+
},
|
123 |
+
{
|
124 |
+
"cell_type": "code",
|
125 |
+
"execution_count": null,
|
126 |
+
"id": "9ee257a7",
|
127 |
+
"metadata": {},
|
128 |
+
"outputs": [],
|
129 |
+
"source": [
|
130 |
+
"image1 = np.asarray(Image.open('<path_to_first_image>'))\n",
|
131 |
+
"image2 = np.asarray(Image.open('<path_to_second_image>'))"
|
132 |
+
]
|
133 |
+
},
|
134 |
+
{
|
135 |
+
"cell_type": "code",
|
136 |
+
"execution_count": null,
|
137 |
+
"id": "d5edccf0",
|
138 |
+
"metadata": {},
|
139 |
+
"outputs": [],
|
140 |
+
"source": [
|
141 |
+
"model, _, cropsize, with_conf, task, tile_conf_mode = _load_model_and_criterion('stereoflow_models/crocoflow.pth', None, device)\n"
|
142 |
+
]
|
143 |
+
},
|
144 |
+
{
|
145 |
+
"cell_type": "code",
|
146 |
+
"execution_count": null,
|
147 |
+
"id": "b19692c3",
|
148 |
+
"metadata": {},
|
149 |
+
"outputs": [],
|
150 |
+
"source": [
|
151 |
+
"im1 = img_to_tensor(image1).to(device).unsqueeze(0)\n",
|
152 |
+
"im2 = img_to_tensor(image2).to(device).unsqueeze(0)\n",
|
153 |
+
"with torch.inference_mode():\n",
|
154 |
+
" pred, _, _ = tiled_pred(model, None, im1, im2, None, conf_mode=tile_conf_mode, overlap=tile_overlap, crop=cropsize, with_conf=with_conf, return_time=False)\n",
|
155 |
+
"pred = pred.squeeze(0).permute(1,2,0).cpu().numpy()"
|
156 |
+
]
|
157 |
+
},
|
158 |
+
{
|
159 |
+
"cell_type": "code",
|
160 |
+
"execution_count": null,
|
161 |
+
"id": "26f79db3",
|
162 |
+
"metadata": {},
|
163 |
+
"outputs": [],
|
164 |
+
"source": [
|
165 |
+
"plt.imshow(flowToColor(pred))\n",
|
166 |
+
"plt.axis('off')"
|
167 |
+
]
|
168 |
+
}
|
169 |
+
],
|
170 |
+
"metadata": {
|
171 |
+
"kernelspec": {
|
172 |
+
"display_name": "Python 3 (ipykernel)",
|
173 |
+
"language": "python",
|
174 |
+
"name": "python3"
|
175 |
+
},
|
176 |
+
"language_info": {
|
177 |
+
"codemirror_mode": {
|
178 |
+
"name": "ipython",
|
179 |
+
"version": 3
|
180 |
+
},
|
181 |
+
"file_extension": ".py",
|
182 |
+
"mimetype": "text/x-python",
|
183 |
+
"name": "python",
|
184 |
+
"nbconvert_exporter": "python",
|
185 |
+
"pygments_lexer": "ipython3",
|
186 |
+
"version": "3.9.7"
|
187 |
+
}
|
188 |
+
},
|
189 |
+
"nbformat": 4,
|
190 |
+
"nbformat_minor": 5
|
191 |
+
}
|
third_party/mast3r/dust3r/croco/datasets/__init__.py
ADDED
File without changes
|
third_party/mast3r/dust3r/croco/datasets/crops/README.MD
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
## Generation of crops from the real datasets
|
2 |
+
|
3 |
+
The instructions below allow to generate the crops used for pre-training CroCo v2 from the following real-world datasets: ARKitScenes, MegaDepth, 3DStreetView and IndoorVL.
|
4 |
+
|
5 |
+
### Download the metadata of the crops to generate
|
6 |
+
|
7 |
+
First, download the metadata and put them in `./data/`:
|
8 |
+
```
|
9 |
+
mkdir -p data
|
10 |
+
cd data/
|
11 |
+
wget https://download.europe.naverlabs.com/ComputerVision/CroCo/data/crop_metadata.zip
|
12 |
+
unzip crop_metadata.zip
|
13 |
+
rm crop_metadata.zip
|
14 |
+
cd ..
|
15 |
+
```
|
16 |
+
|
17 |
+
### Prepare the original datasets
|
18 |
+
|
19 |
+
Second, download the original datasets in `./data/original_datasets/`.
|
20 |
+
```
|
21 |
+
mkdir -p data/original_datasets
|
22 |
+
```
|
23 |
+
|
24 |
+
##### ARKitScenes
|
25 |
+
|
26 |
+
Download the `raw` dataset from https://github.com/apple/ARKitScenes/blob/main/DATA.md and put it in `./data/original_datasets/ARKitScenes/`.
|
27 |
+
The resulting file structure should be like:
|
28 |
+
```
|
29 |
+
./data/original_datasets/ARKitScenes/
|
30 |
+
└───Training
|
31 |
+
└───40753679
|
32 |
+
│ │ ultrawide
|
33 |
+
│ │ ...
|
34 |
+
└───40753686
|
35 |
+
│
|
36 |
+
...
|
37 |
+
```
|
38 |
+
|
39 |
+
##### MegaDepth
|
40 |
+
|
41 |
+
Download `MegaDepth v1 Dataset` from https://www.cs.cornell.edu/projects/megadepth/ and put it in `./data/original_datasets/MegaDepth/`.
|
42 |
+
The resulting file structure should be like:
|
43 |
+
|
44 |
+
```
|
45 |
+
./data/original_datasets/MegaDepth/
|
46 |
+
└───0000
|
47 |
+
│ └───images
|
48 |
+
│ │ │ 1000557903_87fa96b8a4_o.jpg
|
49 |
+
│ │ └ ...
|
50 |
+
│ └─── ...
|
51 |
+
└───0001
|
52 |
+
│ │
|
53 |
+
│ └ ...
|
54 |
+
└─── ...
|
55 |
+
```
|
56 |
+
|
57 |
+
##### 3DStreetView
|
58 |
+
|
59 |
+
Download `3D_Street_View` dataset from https://github.com/amir32002/3D_Street_View and put it in `./data/original_datasets/3DStreetView/`.
|
60 |
+
The resulting file structure should be like:
|
61 |
+
|
62 |
+
```
|
63 |
+
./data/original_datasets/3DStreetView/
|
64 |
+
└───dataset_aligned
|
65 |
+
│ └───0002
|
66 |
+
│ │ │ 0000002_0000001_0000002_0000001.jpg
|
67 |
+
│ │ └ ...
|
68 |
+
│ └─── ...
|
69 |
+
└───dataset_unaligned
|
70 |
+
│ └───0003
|
71 |
+
│ │ │ 0000003_0000001_0000002_0000001.jpg
|
72 |
+
│ │ └ ...
|
73 |
+
│ └─── ...
|
74 |
+
```
|
75 |
+
|
76 |
+
##### IndoorVL
|
77 |
+
|
78 |
+
Download the `IndoorVL` datasets using [Kapture](https://github.com/naver/kapture).
|
79 |
+
|
80 |
+
```
|
81 |
+
pip install kapture
|
82 |
+
mkdir -p ./data/original_datasets/IndoorVL
|
83 |
+
cd ./data/original_datasets/IndoorVL
|
84 |
+
kapture_download_dataset.py update
|
85 |
+
kapture_download_dataset.py install "HyundaiDepartmentStore_*"
|
86 |
+
kapture_download_dataset.py install "GangnamStation_*"
|
87 |
+
cd -
|
88 |
+
```
|
89 |
+
|
90 |
+
### Extract the crops
|
91 |
+
|
92 |
+
Now, extract the crops for each of the dataset:
|
93 |
+
```
|
94 |
+
for dataset in ARKitScenes MegaDepth 3DStreetView IndoorVL;
|
95 |
+
do
|
96 |
+
python3 datasets/crops/extract_crops_from_images.py --crops ./data/crop_metadata/${dataset}/crops_release.txt --root-dir ./data/original_datasets/${dataset}/ --output-dir ./data/${dataset}_crops/ --imsize 256 --nthread 8 --max-subdir-levels 5 --ideal-number-pairs-in-dir 500;
|
97 |
+
done
|
98 |
+
```
|
99 |
+
|
100 |
+
##### Note for IndoorVL
|
101 |
+
|
102 |
+
Due to some legal issues, we can only release 144,228 pairs out of the 1,593,689 pairs used in the paper.
|
103 |
+
To account for it in terms of number of pre-training iterations, the pre-training command in this repository uses 125 training epochs including 12 warm-up epochs and learning rate cosine schedule of 250, instead of 100, 10 and 200 respectively.
|
104 |
+
The impact on the performance is negligible.
|
third_party/mast3r/dust3r/croco/datasets/crops/extract_crops_from_images.py
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2022-present Naver Corporation. All rights reserved.
|
2 |
+
# Licensed under CC BY-NC-SA 4.0 (non-commercial use only).
|
3 |
+
#
|
4 |
+
# --------------------------------------------------------
|
5 |
+
# Extracting crops for pre-training
|
6 |
+
# --------------------------------------------------------
|
7 |
+
|
8 |
+
import os
|
9 |
+
import argparse
|
10 |
+
from tqdm import tqdm
|
11 |
+
from PIL import Image
|
12 |
+
import functools
|
13 |
+
from multiprocessing import Pool
|
14 |
+
import math
|
15 |
+
|
16 |
+
|
17 |
+
def arg_parser():
|
18 |
+
parser = argparse.ArgumentParser('Generate cropped image pairs from image crop list')
|
19 |
+
|
20 |
+
parser.add_argument('--crops', type=str, required=True, help='crop file')
|
21 |
+
parser.add_argument('--root-dir', type=str, required=True, help='root directory')
|
22 |
+
parser.add_argument('--output-dir', type=str, required=True, help='output directory')
|
23 |
+
parser.add_argument('--imsize', type=int, default=256, help='size of the crops')
|
24 |
+
parser.add_argument('--nthread', type=int, required=True, help='number of simultaneous threads')
|
25 |
+
parser.add_argument('--max-subdir-levels', type=int, default=5, help='maximum number of subdirectories')
|
26 |
+
parser.add_argument('--ideal-number-pairs-in-dir', type=int, default=500, help='number of pairs stored in a dir')
|
27 |
+
return parser
|
28 |
+
|
29 |
+
|
30 |
+
def main(args):
|
31 |
+
listing_path = os.path.join(args.output_dir, 'listing.txt')
|
32 |
+
|
33 |
+
print(f'Loading list of crops ... ({args.nthread} threads)')
|
34 |
+
crops, num_crops_to_generate = load_crop_file(args.crops)
|
35 |
+
|
36 |
+
print(f'Preparing jobs ({len(crops)} candidate image pairs)...')
|
37 |
+
num_levels = min(math.ceil(math.log(num_crops_to_generate, args.ideal_number_pairs_in_dir)), args.max_subdir_levels)
|
38 |
+
num_pairs_in_dir = math.ceil(num_crops_to_generate ** (1/num_levels))
|
39 |
+
|
40 |
+
jobs = prepare_jobs(crops, num_levels, num_pairs_in_dir)
|
41 |
+
del crops
|
42 |
+
|
43 |
+
os.makedirs(args.output_dir, exist_ok=True)
|
44 |
+
mmap = Pool(args.nthread).imap_unordered if args.nthread > 1 else map
|
45 |
+
call = functools.partial(save_image_crops, args)
|
46 |
+
|
47 |
+
print(f"Generating cropped images to {args.output_dir} ...")
|
48 |
+
with open(listing_path, 'w') as listing:
|
49 |
+
listing.write('# pair_path\n')
|
50 |
+
for results in tqdm(mmap(call, jobs), total=len(jobs)):
|
51 |
+
for path in results:
|
52 |
+
listing.write(f'{path}\n')
|
53 |
+
print('Finished writing listing to', listing_path)
|
54 |
+
|
55 |
+
|
56 |
+
def load_crop_file(path):
|
57 |
+
data = open(path).read().splitlines()
|
58 |
+
pairs = []
|
59 |
+
num_crops_to_generate = 0
|
60 |
+
for line in tqdm(data):
|
61 |
+
if line.startswith('#'):
|
62 |
+
continue
|
63 |
+
line = line.split(', ')
|
64 |
+
if len(line) < 8:
|
65 |
+
img1, img2, rotation = line
|
66 |
+
pairs.append((img1, img2, int(rotation), []))
|
67 |
+
else:
|
68 |
+
l1, r1, t1, b1, l2, r2, t2, b2 = map(int, line)
|
69 |
+
rect1, rect2 = (l1, t1, r1, b1), (l2, t2, r2, b2)
|
70 |
+
pairs[-1][-1].append((rect1, rect2))
|
71 |
+
num_crops_to_generate += 1
|
72 |
+
return pairs, num_crops_to_generate
|
73 |
+
|
74 |
+
|
75 |
+
def prepare_jobs(pairs, num_levels, num_pairs_in_dir):
|
76 |
+
jobs = []
|
77 |
+
powers = [num_pairs_in_dir**level for level in reversed(range(num_levels))]
|
78 |
+
|
79 |
+
def get_path(idx):
|
80 |
+
idx_array = []
|
81 |
+
d = idx
|
82 |
+
for level in range(num_levels - 1):
|
83 |
+
idx_array.append(idx // powers[level])
|
84 |
+
idx = idx % powers[level]
|
85 |
+
idx_array.append(d)
|
86 |
+
return '/'.join(map(lambda x: hex(x)[2:], idx_array))
|
87 |
+
|
88 |
+
idx = 0
|
89 |
+
for pair_data in tqdm(pairs):
|
90 |
+
img1, img2, rotation, crops = pair_data
|
91 |
+
if -60 <= rotation and rotation <= 60:
|
92 |
+
rotation = 0 # most likely not a true rotation
|
93 |
+
paths = [get_path(idx + k) for k in range(len(crops))]
|
94 |
+
idx += len(crops)
|
95 |
+
jobs.append(((img1, img2), rotation, crops, paths))
|
96 |
+
return jobs
|
97 |
+
|
98 |
+
|
99 |
+
def load_image(path):
|
100 |
+
try:
|
101 |
+
return Image.open(path).convert('RGB')
|
102 |
+
except Exception as e:
|
103 |
+
print('skipping', path, e)
|
104 |
+
raise OSError()
|
105 |
+
|
106 |
+
|
107 |
+
def save_image_crops(args, data):
|
108 |
+
# load images
|
109 |
+
img_pair, rot, crops, paths = data
|
110 |
+
try:
|
111 |
+
img1, img2 = [load_image(os.path.join(args.root_dir, impath)) for impath in img_pair]
|
112 |
+
except OSError as e:
|
113 |
+
return []
|
114 |
+
|
115 |
+
def area(sz):
|
116 |
+
return sz[0] * sz[1]
|
117 |
+
|
118 |
+
tgt_size = (args.imsize, args.imsize)
|
119 |
+
|
120 |
+
def prepare_crop(img, rect, rot=0):
|
121 |
+
# actual crop
|
122 |
+
img = img.crop(rect)
|
123 |
+
|
124 |
+
# resize to desired size
|
125 |
+
interp = Image.Resampling.LANCZOS if area(img.size) > 4*area(tgt_size) else Image.Resampling.BICUBIC
|
126 |
+
img = img.resize(tgt_size, resample=interp)
|
127 |
+
|
128 |
+
# rotate the image
|
129 |
+
rot90 = (round(rot/90) % 4) * 90
|
130 |
+
if rot90 == 90:
|
131 |
+
img = img.transpose(Image.Transpose.ROTATE_90)
|
132 |
+
elif rot90 == 180:
|
133 |
+
img = img.transpose(Image.Transpose.ROTATE_180)
|
134 |
+
elif rot90 == 270:
|
135 |
+
img = img.transpose(Image.Transpose.ROTATE_270)
|
136 |
+
return img
|
137 |
+
|
138 |
+
results = []
|
139 |
+
for (rect1, rect2), path in zip(crops, paths):
|
140 |
+
crop1 = prepare_crop(img1, rect1)
|
141 |
+
crop2 = prepare_crop(img2, rect2, rot)
|
142 |
+
|
143 |
+
fullpath1 = os.path.join(args.output_dir, path+'_1.jpg')
|
144 |
+
fullpath2 = os.path.join(args.output_dir, path+'_2.jpg')
|
145 |
+
os.makedirs(os.path.dirname(fullpath1), exist_ok=True)
|
146 |
+
|
147 |
+
assert not os.path.isfile(fullpath1), fullpath1
|
148 |
+
assert not os.path.isfile(fullpath2), fullpath2
|
149 |
+
crop1.save(fullpath1)
|
150 |
+
crop2.save(fullpath2)
|
151 |
+
results.append(path)
|
152 |
+
|
153 |
+
return results
|
154 |
+
|
155 |
+
|
156 |
+
if __name__ == '__main__':
|
157 |
+
args = arg_parser().parse_args()
|
158 |
+
main(args)
|
159 |
+
|
third_party/mast3r/dust3r/croco/datasets/habitat_sim/README.MD
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
## Generation of synthetic image pairs using Habitat-Sim
|
2 |
+
|
3 |
+
These instructions allow to generate pre-training pairs from the Habitat simulator.
|
4 |
+
As we did not save metadata of the pairs used in the original paper, they are not strictly the same, but these data use the same setting and are equivalent.
|
5 |
+
|
6 |
+
### Download Habitat-Sim scenes
|
7 |
+
Download Habitat-Sim scenes:
|
8 |
+
- Download links can be found here: https://github.com/facebookresearch/habitat-sim/blob/main/DATASETS.md
|
9 |
+
- We used scenes from the HM3D, habitat-test-scenes, Replica, ReplicaCad and ScanNet datasets.
|
10 |
+
- Please put the scenes under `./data/habitat-sim-data/scene_datasets/` following the structure below, or update manually paths in `paths.py`.
|
11 |
+
```
|
12 |
+
./data/
|
13 |
+
└──habitat-sim-data/
|
14 |
+
└──scene_datasets/
|
15 |
+
├──hm3d/
|
16 |
+
├──gibson/
|
17 |
+
├──habitat-test-scenes/
|
18 |
+
├──replica_cad_baked_lighting/
|
19 |
+
├──replica_cad/
|
20 |
+
├──ReplicaDataset/
|
21 |
+
└──scannet/
|
22 |
+
```
|
23 |
+
|
24 |
+
### Image pairs generation
|
25 |
+
We provide metadata to generate reproducible images pairs for pretraining and validation.
|
26 |
+
Experiments described in the paper used similar data, but whose generation was not reproducible at the time.
|
27 |
+
|
28 |
+
Specifications:
|
29 |
+
- 256x256 resolution images, with 60 degrees field of view .
|
30 |
+
- Up to 1000 image pairs per scene.
|
31 |
+
- Number of scenes considered/number of images pairs per dataset:
|
32 |
+
- Scannet: 1097 scenes / 985 209 pairs
|
33 |
+
- HM3D:
|
34 |
+
- hm3d/train: 800 / 800k pairs
|
35 |
+
- hm3d/val: 100 scenes / 100k pairs
|
36 |
+
- hm3d/minival: 10 scenes / 10k pairs
|
37 |
+
- habitat-test-scenes: 3 scenes / 3k pairs
|
38 |
+
- replica_cad_baked_lighting: 13 scenes / 13k pairs
|
39 |
+
|
40 |
+
- Scenes from hm3d/val and hm3d/minival pairs were not used for the pre-training but kept for validation purposes.
|
41 |
+
|
42 |
+
Download metadata and extract it:
|
43 |
+
```bash
|
44 |
+
mkdir -p data/habitat_release_metadata/
|
45 |
+
cd data/habitat_release_metadata/
|
46 |
+
wget https://download.europe.naverlabs.com/ComputerVision/CroCo/data/habitat_release_metadata/multiview_habitat_metadata.tar.gz
|
47 |
+
tar -xvf multiview_habitat_metadata.tar.gz
|
48 |
+
cd ../..
|
49 |
+
# Location of the metadata
|
50 |
+
METADATA_DIR="./data/habitat_release_metadata/multiview_habitat_metadata"
|
51 |
+
```
|
52 |
+
|
53 |
+
Generate image pairs from metadata:
|
54 |
+
- The following command will print a list of commandlines to generate image pairs for each scene:
|
55 |
+
```bash
|
56 |
+
# Target output directory
|
57 |
+
PAIRS_DATASET_DIR="./data/habitat_release/"
|
58 |
+
python datasets/habitat_sim/generate_from_metadata_files.py --input_dir=$METADATA_DIR --output_dir=$PAIRS_DATASET_DIR
|
59 |
+
```
|
60 |
+
- One can launch multiple of such commands in parallel e.g. using GNU Parallel:
|
61 |
+
```bash
|
62 |
+
python datasets/habitat_sim/generate_from_metadata_files.py --input_dir=$METADATA_DIR --output_dir=$PAIRS_DATASET_DIR | parallel -j 16
|
63 |
+
```
|
64 |
+
|
65 |
+
## Metadata generation
|
66 |
+
|
67 |
+
Image pairs were randomly sampled using the following commands, whose outputs contain randomness and are thus not exactly reproducible:
|
68 |
+
```bash
|
69 |
+
# Print commandlines to generate image pairs from the different scenes available.
|
70 |
+
PAIRS_DATASET_DIR=MY_CUSTOM_PATH
|
71 |
+
python datasets/habitat_sim/generate_multiview_images.py --list_commands --output_dir=$PAIRS_DATASET_DIR
|
72 |
+
|
73 |
+
# Once a dataset is generated, pack metadata files for reproducibility.
|
74 |
+
METADATA_DIR=MY_CUSTON_PATH
|
75 |
+
python datasets/habitat_sim/pack_metadata_files.py $PAIRS_DATASET_DIR $METADATA_DIR
|
76 |
+
```
|
third_party/mast3r/dust3r/croco/datasets/habitat_sim/__init__.py
ADDED
File without changes
|
third_party/mast3r/dust3r/croco/datasets/habitat_sim/generate_from_metadata.py
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2022-present Naver Corporation. All rights reserved.
|
2 |
+
# Licensed under CC BY-NC-SA 4.0 (non-commercial use only).
|
3 |
+
|
4 |
+
"""
|
5 |
+
Script to generate image pairs for a given scene reproducing poses provided in a metadata file.
|
6 |
+
"""
|
7 |
+
import os
|
8 |
+
from datasets.habitat_sim.multiview_habitat_sim_generator import MultiviewHabitatSimGenerator
|
9 |
+
from datasets.habitat_sim.paths import SCENES_DATASET
|
10 |
+
import argparse
|
11 |
+
import quaternion
|
12 |
+
import PIL.Image
|
13 |
+
import cv2
|
14 |
+
import json
|
15 |
+
from tqdm import tqdm
|
16 |
+
|
17 |
+
def generate_multiview_images_from_metadata(metadata_filename,
|
18 |
+
output_dir,
|
19 |
+
overload_params = dict(),
|
20 |
+
scene_datasets_paths=None,
|
21 |
+
exist_ok=False):
|
22 |
+
"""
|
23 |
+
Generate images from a metadata file for reproducibility purposes.
|
24 |
+
"""
|
25 |
+
# Reorder paths by decreasing label length, to avoid collisions when testing if a string by such label
|
26 |
+
if scene_datasets_paths is not None:
|
27 |
+
scene_datasets_paths = dict(sorted(scene_datasets_paths.items(), key= lambda x: len(x[0]), reverse=True))
|
28 |
+
|
29 |
+
with open(metadata_filename, 'r') as f:
|
30 |
+
input_metadata = json.load(f)
|
31 |
+
metadata = dict()
|
32 |
+
for key, value in input_metadata.items():
|
33 |
+
# Optionally replace some paths
|
34 |
+
if key in ("scene_dataset_config_file", "scene", "navmesh") and value != "":
|
35 |
+
if scene_datasets_paths is not None:
|
36 |
+
for dataset_label, dataset_path in scene_datasets_paths.items():
|
37 |
+
if value.startswith(dataset_label):
|
38 |
+
value = os.path.normpath(os.path.join(dataset_path, os.path.relpath(value, dataset_label)))
|
39 |
+
break
|
40 |
+
metadata[key] = value
|
41 |
+
|
42 |
+
# Overload some parameters
|
43 |
+
for key, value in overload_params.items():
|
44 |
+
metadata[key] = value
|
45 |
+
|
46 |
+
generation_entries = dict([(key, value) for key, value in metadata.items() if not (key in ('multiviews', 'output_dir', 'generate_depth'))])
|
47 |
+
generate_depth = metadata["generate_depth"]
|
48 |
+
|
49 |
+
os.makedirs(output_dir, exist_ok=exist_ok)
|
50 |
+
|
51 |
+
generator = MultiviewHabitatSimGenerator(**generation_entries)
|
52 |
+
|
53 |
+
# Generate views
|
54 |
+
for idx_label, data in tqdm(metadata['multiviews'].items()):
|
55 |
+
positions = data["positions"]
|
56 |
+
orientations = data["orientations"]
|
57 |
+
n = len(positions)
|
58 |
+
for oidx in range(n):
|
59 |
+
observation = generator.render_viewpoint(positions[oidx], quaternion.from_float_array(orientations[oidx]))
|
60 |
+
observation_label = f"{oidx + 1}" # Leonid is indexing starting from 1
|
61 |
+
# Color image saved using PIL
|
62 |
+
img = PIL.Image.fromarray(observation['color'][:,:,:3])
|
63 |
+
filename = os.path.join(output_dir, f"{idx_label}_{observation_label}.jpeg")
|
64 |
+
img.save(filename)
|
65 |
+
if generate_depth:
|
66 |
+
# Depth image as EXR file
|
67 |
+
filename = os.path.join(output_dir, f"{idx_label}_{observation_label}_depth.exr")
|
68 |
+
cv2.imwrite(filename, observation['depth'], [cv2.IMWRITE_EXR_TYPE, cv2.IMWRITE_EXR_TYPE_HALF])
|
69 |
+
# Camera parameters
|
70 |
+
camera_params = dict([(key, observation[key].tolist()) for key in ("camera_intrinsics", "R_cam2world", "t_cam2world")])
|
71 |
+
filename = os.path.join(output_dir, f"{idx_label}_{observation_label}_camera_params.json")
|
72 |
+
with open(filename, "w") as f:
|
73 |
+
json.dump(camera_params, f)
|
74 |
+
# Save metadata
|
75 |
+
with open(os.path.join(output_dir, "metadata.json"), "w") as f:
|
76 |
+
json.dump(metadata, f)
|
77 |
+
|
78 |
+
generator.close()
|
79 |
+
|
80 |
+
if __name__ == "__main__":
|
81 |
+
parser = argparse.ArgumentParser()
|
82 |
+
parser.add_argument("--metadata_filename", required=True)
|
83 |
+
parser.add_argument("--output_dir", required=True)
|
84 |
+
args = parser.parse_args()
|
85 |
+
|
86 |
+
generate_multiview_images_from_metadata(metadata_filename=args.metadata_filename,
|
87 |
+
output_dir=args.output_dir,
|
88 |
+
scene_datasets_paths=SCENES_DATASET,
|
89 |
+
overload_params=dict(),
|
90 |
+
exist_ok=True)
|
91 |
+
|
92 |
+
|
third_party/mast3r/dust3r/croco/datasets/habitat_sim/generate_from_metadata_files.py
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2022-present Naver Corporation. All rights reserved.
|
2 |
+
# Licensed under CC BY-NC-SA 4.0 (non-commercial use only).
|
3 |
+
|
4 |
+
"""
|
5 |
+
Script generating commandlines to generate image pairs from metadata files.
|
6 |
+
"""
|
7 |
+
import os
|
8 |
+
import glob
|
9 |
+
from tqdm import tqdm
|
10 |
+
import argparse
|
11 |
+
|
12 |
+
if __name__ == "__main__":
|
13 |
+
parser = argparse.ArgumentParser()
|
14 |
+
parser.add_argument("--input_dir", required=True)
|
15 |
+
parser.add_argument("--output_dir", required=True)
|
16 |
+
parser.add_argument("--prefix", default="", help="Commanline prefix, useful e.g. to setup environment.")
|
17 |
+
args = parser.parse_args()
|
18 |
+
|
19 |
+
input_metadata_filenames = glob.iglob(f"{args.input_dir}/**/metadata.json", recursive=True)
|
20 |
+
|
21 |
+
for metadata_filename in tqdm(input_metadata_filenames):
|
22 |
+
output_dir = os.path.join(args.output_dir, os.path.relpath(os.path.dirname(metadata_filename), args.input_dir))
|
23 |
+
# Do not process the scene if the metadata file already exists
|
24 |
+
if os.path.exists(os.path.join(output_dir, "metadata.json")):
|
25 |
+
continue
|
26 |
+
commandline = f"{args.prefix}python datasets/habitat_sim/generate_from_metadata.py --metadata_filename={metadata_filename} --output_dir={output_dir}"
|
27 |
+
print(commandline)
|
third_party/mast3r/dust3r/croco/datasets/habitat_sim/generate_multiview_images.py
ADDED
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2022-present Naver Corporation. All rights reserved.
|
2 |
+
# Licensed under CC BY-NC-SA 4.0 (non-commercial use only).
|
3 |
+
|
4 |
+
import os
|
5 |
+
from tqdm import tqdm
|
6 |
+
import argparse
|
7 |
+
import PIL.Image
|
8 |
+
import numpy as np
|
9 |
+
import json
|
10 |
+
from datasets.habitat_sim.multiview_habitat_sim_generator import MultiviewHabitatSimGenerator, NoNaviguableSpaceError
|
11 |
+
from datasets.habitat_sim.paths import list_scenes_available
|
12 |
+
import cv2
|
13 |
+
import quaternion
|
14 |
+
import shutil
|
15 |
+
|
16 |
+
def generate_multiview_images_for_scene(scene_dataset_config_file,
|
17 |
+
scene,
|
18 |
+
navmesh,
|
19 |
+
output_dir,
|
20 |
+
views_count,
|
21 |
+
size,
|
22 |
+
exist_ok=False,
|
23 |
+
generate_depth=False,
|
24 |
+
**kwargs):
|
25 |
+
"""
|
26 |
+
Generate tuples of overlapping views for a given scene.
|
27 |
+
generate_depth: generate depth images and camera parameters.
|
28 |
+
"""
|
29 |
+
if os.path.exists(output_dir) and not exist_ok:
|
30 |
+
print(f"Scene {scene}: data already generated. Ignoring generation.")
|
31 |
+
return
|
32 |
+
try:
|
33 |
+
print(f"Scene {scene}: {size} multiview acquisitions to generate...")
|
34 |
+
os.makedirs(output_dir, exist_ok=exist_ok)
|
35 |
+
|
36 |
+
metadata_filename = os.path.join(output_dir, "metadata.json")
|
37 |
+
|
38 |
+
metadata_template = dict(scene_dataset_config_file=scene_dataset_config_file,
|
39 |
+
scene=scene,
|
40 |
+
navmesh=navmesh,
|
41 |
+
views_count=views_count,
|
42 |
+
size=size,
|
43 |
+
generate_depth=generate_depth,
|
44 |
+
**kwargs)
|
45 |
+
metadata_template["multiviews"] = dict()
|
46 |
+
|
47 |
+
if os.path.exists(metadata_filename):
|
48 |
+
print("Metadata file already exists:", metadata_filename)
|
49 |
+
print("Loading already generated metadata file...")
|
50 |
+
with open(metadata_filename, "r") as f:
|
51 |
+
metadata = json.load(f)
|
52 |
+
|
53 |
+
for key in metadata_template.keys():
|
54 |
+
if key != "multiviews":
|
55 |
+
assert metadata_template[key] == metadata[key], f"existing file is inconsistent with the input parameters:\nKey: {key}\nmetadata: {metadata[key]}\ntemplate: {metadata_template[key]}."
|
56 |
+
else:
|
57 |
+
print("No temporary file found. Starting generation from scratch...")
|
58 |
+
metadata = metadata_template
|
59 |
+
|
60 |
+
starting_id = len(metadata["multiviews"])
|
61 |
+
print(f"Starting generation from index {starting_id}/{size}...")
|
62 |
+
if starting_id >= size:
|
63 |
+
print("Generation already done.")
|
64 |
+
return
|
65 |
+
|
66 |
+
generator = MultiviewHabitatSimGenerator(scene_dataset_config_file=scene_dataset_config_file,
|
67 |
+
scene=scene,
|
68 |
+
navmesh=navmesh,
|
69 |
+
views_count = views_count,
|
70 |
+
size = size,
|
71 |
+
**kwargs)
|
72 |
+
|
73 |
+
for idx in tqdm(range(starting_id, size)):
|
74 |
+
# Generate / re-generate the observations
|
75 |
+
try:
|
76 |
+
data = generator[idx]
|
77 |
+
observations = data["observations"]
|
78 |
+
positions = data["positions"]
|
79 |
+
orientations = data["orientations"]
|
80 |
+
|
81 |
+
idx_label = f"{idx:08}"
|
82 |
+
for oidx, observation in enumerate(observations):
|
83 |
+
observation_label = f"{oidx + 1}" # Leonid is indexing starting from 1
|
84 |
+
# Color image saved using PIL
|
85 |
+
img = PIL.Image.fromarray(observation['color'][:,:,:3])
|
86 |
+
filename = os.path.join(output_dir, f"{idx_label}_{observation_label}.jpeg")
|
87 |
+
img.save(filename)
|
88 |
+
if generate_depth:
|
89 |
+
# Depth image as EXR file
|
90 |
+
filename = os.path.join(output_dir, f"{idx_label}_{observation_label}_depth.exr")
|
91 |
+
cv2.imwrite(filename, observation['depth'], [cv2.IMWRITE_EXR_TYPE, cv2.IMWRITE_EXR_TYPE_HALF])
|
92 |
+
# Camera parameters
|
93 |
+
camera_params = dict([(key, observation[key].tolist()) for key in ("camera_intrinsics", "R_cam2world", "t_cam2world")])
|
94 |
+
filename = os.path.join(output_dir, f"{idx_label}_{observation_label}_camera_params.json")
|
95 |
+
with open(filename, "w") as f:
|
96 |
+
json.dump(camera_params, f)
|
97 |
+
metadata["multiviews"][idx_label] = {"positions": positions.tolist(),
|
98 |
+
"orientations": orientations.tolist(),
|
99 |
+
"covisibility_ratios": data["covisibility_ratios"].tolist(),
|
100 |
+
"valid_fractions": data["valid_fractions"].tolist(),
|
101 |
+
"pairwise_visibility_ratios": data["pairwise_visibility_ratios"].tolist()}
|
102 |
+
except RecursionError:
|
103 |
+
print("Recursion error: unable to sample observations for this scene. We will stop there.")
|
104 |
+
break
|
105 |
+
|
106 |
+
# Regularly save a temporary metadata file, in case we need to restart the generation
|
107 |
+
if idx % 10 == 0:
|
108 |
+
with open(metadata_filename, "w") as f:
|
109 |
+
json.dump(metadata, f)
|
110 |
+
|
111 |
+
# Save metadata
|
112 |
+
with open(metadata_filename, "w") as f:
|
113 |
+
json.dump(metadata, f)
|
114 |
+
|
115 |
+
generator.close()
|
116 |
+
except NoNaviguableSpaceError:
|
117 |
+
pass
|
118 |
+
|
119 |
+
def create_commandline(scene_data, generate_depth, exist_ok=False):
|
120 |
+
"""
|
121 |
+
Create a commandline string to generate a scene.
|
122 |
+
"""
|
123 |
+
def my_formatting(val):
|
124 |
+
if val is None or val == "":
|
125 |
+
return '""'
|
126 |
+
else:
|
127 |
+
return val
|
128 |
+
commandline = f"""python {__file__} --scene {my_formatting(scene_data.scene)}
|
129 |
+
--scene_dataset_config_file {my_formatting(scene_data.scene_dataset_config_file)}
|
130 |
+
--navmesh {my_formatting(scene_data.navmesh)}
|
131 |
+
--output_dir {my_formatting(scene_data.output_dir)}
|
132 |
+
--generate_depth {int(generate_depth)}
|
133 |
+
--exist_ok {int(exist_ok)}
|
134 |
+
"""
|
135 |
+
commandline = " ".join(commandline.split())
|
136 |
+
return commandline
|
137 |
+
|
138 |
+
if __name__ == "__main__":
|
139 |
+
os.umask(2)
|
140 |
+
|
141 |
+
parser = argparse.ArgumentParser(description="""Example of use -- listing commands to generate data for scenes available:
|
142 |
+
> python datasets/habitat_sim/generate_multiview_habitat_images.py --list_commands
|
143 |
+
""")
|
144 |
+
|
145 |
+
parser.add_argument("--output_dir", type=str, required=True)
|
146 |
+
parser.add_argument("--list_commands", action='store_true', help="list commandlines to run if true")
|
147 |
+
parser.add_argument("--scene", type=str, default="")
|
148 |
+
parser.add_argument("--scene_dataset_config_file", type=str, default="")
|
149 |
+
parser.add_argument("--navmesh", type=str, default="")
|
150 |
+
|
151 |
+
parser.add_argument("--generate_depth", type=int, default=1)
|
152 |
+
parser.add_argument("--exist_ok", type=int, default=0)
|
153 |
+
|
154 |
+
kwargs = dict(resolution=(256,256), hfov=60, views_count = 2, size=1000)
|
155 |
+
|
156 |
+
args = parser.parse_args()
|
157 |
+
generate_depth=bool(args.generate_depth)
|
158 |
+
exist_ok = bool(args.exist_ok)
|
159 |
+
|
160 |
+
if args.list_commands:
|
161 |
+
# Listing scenes available...
|
162 |
+
scenes_data = list_scenes_available(base_output_dir=args.output_dir)
|
163 |
+
|
164 |
+
for scene_data in scenes_data:
|
165 |
+
print(create_commandline(scene_data, generate_depth=generate_depth, exist_ok=exist_ok))
|
166 |
+
else:
|
167 |
+
if args.scene == "" or args.output_dir == "":
|
168 |
+
print("Missing scene or output dir argument!")
|
169 |
+
print(parser.format_help())
|
170 |
+
else:
|
171 |
+
generate_multiview_images_for_scene(scene=args.scene,
|
172 |
+
scene_dataset_config_file = args.scene_dataset_config_file,
|
173 |
+
navmesh = args.navmesh,
|
174 |
+
output_dir = args.output_dir,
|
175 |
+
exist_ok=exist_ok,
|
176 |
+
generate_depth=generate_depth,
|
177 |
+
**kwargs)
|
third_party/mast3r/dust3r/croco/datasets/habitat_sim/multiview_habitat_sim_generator.py
ADDED
@@ -0,0 +1,390 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2022-present Naver Corporation. All rights reserved.
|
2 |
+
# Licensed under CC BY-NC-SA 4.0 (non-commercial use only).
|
3 |
+
|
4 |
+
import os
|
5 |
+
import numpy as np
|
6 |
+
import quaternion
|
7 |
+
import habitat_sim
|
8 |
+
import json
|
9 |
+
from sklearn.neighbors import NearestNeighbors
|
10 |
+
import cv2
|
11 |
+
|
12 |
+
# OpenCV to habitat camera convention transformation
|
13 |
+
R_OPENCV2HABITAT = np.stack((habitat_sim.geo.RIGHT, -habitat_sim.geo.UP, habitat_sim.geo.FRONT), axis=0)
|
14 |
+
R_HABITAT2OPENCV = R_OPENCV2HABITAT.T
|
15 |
+
DEG2RAD = np.pi / 180
|
16 |
+
|
17 |
+
def compute_camera_intrinsics(height, width, hfov):
|
18 |
+
f = width/2 / np.tan(hfov/2 * np.pi/180)
|
19 |
+
cu, cv = width/2, height/2
|
20 |
+
return f, cu, cv
|
21 |
+
|
22 |
+
def compute_camera_pose_opencv_convention(camera_position, camera_orientation):
|
23 |
+
R_cam2world = quaternion.as_rotation_matrix(camera_orientation) @ R_OPENCV2HABITAT
|
24 |
+
t_cam2world = np.asarray(camera_position)
|
25 |
+
return R_cam2world, t_cam2world
|
26 |
+
|
27 |
+
def compute_pointmap(depthmap, hfov):
|
28 |
+
""" Compute a HxWx3 pointmap in camera frame from a HxW depth map."""
|
29 |
+
height, width = depthmap.shape
|
30 |
+
f, cu, cv = compute_camera_intrinsics(height, width, hfov)
|
31 |
+
# Cast depth map to point
|
32 |
+
z_cam = depthmap
|
33 |
+
u, v = np.meshgrid(range(width), range(height))
|
34 |
+
x_cam = (u - cu) / f * z_cam
|
35 |
+
y_cam = (v - cv) / f * z_cam
|
36 |
+
X_cam = np.stack((x_cam, y_cam, z_cam), axis=-1)
|
37 |
+
return X_cam
|
38 |
+
|
39 |
+
def compute_pointcloud(depthmap, hfov, camera_position, camera_rotation):
|
40 |
+
"""Return a 3D point cloud corresponding to valid pixels of the depth map"""
|
41 |
+
R_cam2world, t_cam2world = compute_camera_pose_opencv_convention(camera_position, camera_rotation)
|
42 |
+
|
43 |
+
X_cam = compute_pointmap(depthmap=depthmap, hfov=hfov)
|
44 |
+
valid_mask = (X_cam[:,:,2] != 0.0)
|
45 |
+
|
46 |
+
X_cam = X_cam.reshape(-1, 3)[valid_mask.flatten()]
|
47 |
+
X_world = X_cam @ R_cam2world.T + t_cam2world.reshape(1, 3)
|
48 |
+
return X_world
|
49 |
+
|
50 |
+
def compute_pointcloud_overlaps_scikit(pointcloud1, pointcloud2, distance_threshold, compute_symmetric=False):
|
51 |
+
"""
|
52 |
+
Compute 'overlapping' metrics based on a distance threshold between two point clouds.
|
53 |
+
"""
|
54 |
+
nbrs = NearestNeighbors(n_neighbors=1, algorithm = 'kd_tree').fit(pointcloud2)
|
55 |
+
distances, indices = nbrs.kneighbors(pointcloud1)
|
56 |
+
intersection1 = np.count_nonzero(distances.flatten() < distance_threshold)
|
57 |
+
|
58 |
+
data = {"intersection1": intersection1,
|
59 |
+
"size1": len(pointcloud1)}
|
60 |
+
if compute_symmetric:
|
61 |
+
nbrs = NearestNeighbors(n_neighbors=1, algorithm = 'kd_tree').fit(pointcloud1)
|
62 |
+
distances, indices = nbrs.kneighbors(pointcloud2)
|
63 |
+
intersection2 = np.count_nonzero(distances.flatten() < distance_threshold)
|
64 |
+
data["intersection2"] = intersection2
|
65 |
+
data["size2"] = len(pointcloud2)
|
66 |
+
|
67 |
+
return data
|
68 |
+
|
69 |
+
def _append_camera_parameters(observation, hfov, camera_location, camera_rotation):
|
70 |
+
"""
|
71 |
+
Add camera parameters to the observation dictionnary produced by Habitat-Sim
|
72 |
+
In-place modifications.
|
73 |
+
"""
|
74 |
+
R_cam2world, t_cam2world = compute_camera_pose_opencv_convention(camera_location, camera_rotation)
|
75 |
+
height, width = observation['depth'].shape
|
76 |
+
f, cu, cv = compute_camera_intrinsics(height, width, hfov)
|
77 |
+
K = np.asarray([[f, 0, cu],
|
78 |
+
[0, f, cv],
|
79 |
+
[0, 0, 1.0]])
|
80 |
+
observation["camera_intrinsics"] = K
|
81 |
+
observation["t_cam2world"] = t_cam2world
|
82 |
+
observation["R_cam2world"] = R_cam2world
|
83 |
+
|
84 |
+
def look_at(eye, center, up, return_cam2world=True):
|
85 |
+
"""
|
86 |
+
Return camera pose looking at a given center point.
|
87 |
+
Analogous of gluLookAt function, using OpenCV camera convention.
|
88 |
+
"""
|
89 |
+
z = center - eye
|
90 |
+
z /= np.linalg.norm(z, axis=-1, keepdims=True)
|
91 |
+
y = -up
|
92 |
+
y = y - np.sum(y * z, axis=-1, keepdims=True) * z
|
93 |
+
y /= np.linalg.norm(y, axis=-1, keepdims=True)
|
94 |
+
x = np.cross(y, z, axis=-1)
|
95 |
+
|
96 |
+
if return_cam2world:
|
97 |
+
R = np.stack((x, y, z), axis=-1)
|
98 |
+
t = eye
|
99 |
+
else:
|
100 |
+
# World to camera transformation
|
101 |
+
# Transposed matrix
|
102 |
+
R = np.stack((x, y, z), axis=-2)
|
103 |
+
t = - np.einsum('...ij, ...j', R, eye)
|
104 |
+
return R, t
|
105 |
+
|
106 |
+
def look_at_for_habitat(eye, center, up, return_cam2world=True):
|
107 |
+
R, t = look_at(eye, center, up)
|
108 |
+
orientation = quaternion.from_rotation_matrix(R @ R_OPENCV2HABITAT.T)
|
109 |
+
return orientation, t
|
110 |
+
|
111 |
+
def generate_orientation_noise(pan_range, tilt_range, roll_range):
|
112 |
+
return (quaternion.from_rotation_vector(np.random.uniform(*pan_range) * DEG2RAD * habitat_sim.geo.UP)
|
113 |
+
* quaternion.from_rotation_vector(np.random.uniform(*tilt_range) * DEG2RAD * habitat_sim.geo.RIGHT)
|
114 |
+
* quaternion.from_rotation_vector(np.random.uniform(*roll_range) * DEG2RAD * habitat_sim.geo.FRONT))
|
115 |
+
|
116 |
+
|
117 |
+
class NoNaviguableSpaceError(RuntimeError):
|
118 |
+
def __init__(self, *args):
|
119 |
+
super().__init__(*args)
|
120 |
+
|
121 |
+
class MultiviewHabitatSimGenerator:
|
122 |
+
def __init__(self,
|
123 |
+
scene,
|
124 |
+
navmesh,
|
125 |
+
scene_dataset_config_file,
|
126 |
+
resolution = (240, 320),
|
127 |
+
views_count=2,
|
128 |
+
hfov = 60,
|
129 |
+
gpu_id = 0,
|
130 |
+
size = 10000,
|
131 |
+
minimum_covisibility = 0.5,
|
132 |
+
transform = None):
|
133 |
+
self.scene = scene
|
134 |
+
self.navmesh = navmesh
|
135 |
+
self.scene_dataset_config_file = scene_dataset_config_file
|
136 |
+
self.resolution = resolution
|
137 |
+
self.views_count = views_count
|
138 |
+
assert(self.views_count >= 1)
|
139 |
+
self.hfov = hfov
|
140 |
+
self.gpu_id = gpu_id
|
141 |
+
self.size = size
|
142 |
+
self.transform = transform
|
143 |
+
|
144 |
+
# Noise added to camera orientation
|
145 |
+
self.pan_range = (-3, 3)
|
146 |
+
self.tilt_range = (-10, 10)
|
147 |
+
self.roll_range = (-5, 5)
|
148 |
+
|
149 |
+
# Height range to sample cameras
|
150 |
+
self.height_range = (1.2, 1.8)
|
151 |
+
|
152 |
+
# Random steps between the camera views
|
153 |
+
self.random_steps_count = 5
|
154 |
+
self.random_step_variance = 2.0
|
155 |
+
|
156 |
+
# Minimum fraction of the scene which should be valid (well defined depth)
|
157 |
+
self.minimum_valid_fraction = 0.7
|
158 |
+
|
159 |
+
# Distance threshold to see to select pairs
|
160 |
+
self.distance_threshold = 0.05
|
161 |
+
# Minimum IoU of a view point cloud with respect to the reference view to be kept.
|
162 |
+
self.minimum_covisibility = minimum_covisibility
|
163 |
+
|
164 |
+
# Maximum number of retries.
|
165 |
+
self.max_attempts_count = 100
|
166 |
+
|
167 |
+
self.seed = None
|
168 |
+
self._lazy_initialization()
|
169 |
+
|
170 |
+
def _lazy_initialization(self):
|
171 |
+
# Lazy random seeding and instantiation of the simulator to deal with multiprocessing properly
|
172 |
+
if self.seed == None:
|
173 |
+
# Re-seed numpy generator
|
174 |
+
np.random.seed()
|
175 |
+
self.seed = np.random.randint(2**32-1)
|
176 |
+
sim_cfg = habitat_sim.SimulatorConfiguration()
|
177 |
+
sim_cfg.scene_id = self.scene
|
178 |
+
if self.scene_dataset_config_file is not None and self.scene_dataset_config_file != "":
|
179 |
+
sim_cfg.scene_dataset_config_file = self.scene_dataset_config_file
|
180 |
+
sim_cfg.random_seed = self.seed
|
181 |
+
sim_cfg.load_semantic_mesh = False
|
182 |
+
sim_cfg.gpu_device_id = self.gpu_id
|
183 |
+
|
184 |
+
depth_sensor_spec = habitat_sim.CameraSensorSpec()
|
185 |
+
depth_sensor_spec.uuid = "depth"
|
186 |
+
depth_sensor_spec.sensor_type = habitat_sim.SensorType.DEPTH
|
187 |
+
depth_sensor_spec.resolution = self.resolution
|
188 |
+
depth_sensor_spec.hfov = self.hfov
|
189 |
+
depth_sensor_spec.position = [0.0, 0.0, 0]
|
190 |
+
depth_sensor_spec.orientation
|
191 |
+
|
192 |
+
rgb_sensor_spec = habitat_sim.CameraSensorSpec()
|
193 |
+
rgb_sensor_spec.uuid = "color"
|
194 |
+
rgb_sensor_spec.sensor_type = habitat_sim.SensorType.COLOR
|
195 |
+
rgb_sensor_spec.resolution = self.resolution
|
196 |
+
rgb_sensor_spec.hfov = self.hfov
|
197 |
+
rgb_sensor_spec.position = [0.0, 0.0, 0]
|
198 |
+
agent_cfg = habitat_sim.agent.AgentConfiguration(sensor_specifications=[rgb_sensor_spec, depth_sensor_spec])
|
199 |
+
|
200 |
+
cfg = habitat_sim.Configuration(sim_cfg, [agent_cfg])
|
201 |
+
self.sim = habitat_sim.Simulator(cfg)
|
202 |
+
if self.navmesh is not None and self.navmesh != "":
|
203 |
+
# Use pre-computed navmesh when available (usually better than those generated automatically)
|
204 |
+
self.sim.pathfinder.load_nav_mesh(self.navmesh)
|
205 |
+
|
206 |
+
if not self.sim.pathfinder.is_loaded:
|
207 |
+
# Try to compute a navmesh
|
208 |
+
navmesh_settings = habitat_sim.NavMeshSettings()
|
209 |
+
navmesh_settings.set_defaults()
|
210 |
+
self.sim.recompute_navmesh(self.sim.pathfinder, navmesh_settings, True)
|
211 |
+
|
212 |
+
# Ensure that the navmesh is not empty
|
213 |
+
if not self.sim.pathfinder.is_loaded:
|
214 |
+
raise NoNaviguableSpaceError(f"No naviguable location (scene: {self.scene} -- navmesh: {self.navmesh})")
|
215 |
+
|
216 |
+
self.agent = self.sim.initialize_agent(agent_id=0)
|
217 |
+
|
218 |
+
def close(self):
|
219 |
+
self.sim.close()
|
220 |
+
|
221 |
+
def __del__(self):
|
222 |
+
self.sim.close()
|
223 |
+
|
224 |
+
def __len__(self):
|
225 |
+
return self.size
|
226 |
+
|
227 |
+
def sample_random_viewpoint(self):
|
228 |
+
""" Sample a random viewpoint using the navmesh """
|
229 |
+
nav_point = self.sim.pathfinder.get_random_navigable_point()
|
230 |
+
|
231 |
+
# Sample a random viewpoint height
|
232 |
+
viewpoint_height = np.random.uniform(*self.height_range)
|
233 |
+
viewpoint_position = nav_point + viewpoint_height * habitat_sim.geo.UP
|
234 |
+
viewpoint_orientation = quaternion.from_rotation_vector(np.random.uniform(0, 2 * np.pi) * habitat_sim.geo.UP) * generate_orientation_noise(self.pan_range, self.tilt_range, self.roll_range)
|
235 |
+
return viewpoint_position, viewpoint_orientation, nav_point
|
236 |
+
|
237 |
+
def sample_other_random_viewpoint(self, observed_point, nav_point):
|
238 |
+
""" Sample a random viewpoint close to an existing one, using the navmesh and a reference observed point."""
|
239 |
+
other_nav_point = nav_point
|
240 |
+
|
241 |
+
walk_directions = self.random_step_variance * np.asarray([1,0,1])
|
242 |
+
for i in range(self.random_steps_count):
|
243 |
+
temp = self.sim.pathfinder.snap_point(other_nav_point + walk_directions * np.random.normal(size=3))
|
244 |
+
# Snapping may return nan when it fails
|
245 |
+
if not np.isnan(temp[0]):
|
246 |
+
other_nav_point = temp
|
247 |
+
|
248 |
+
other_viewpoint_height = np.random.uniform(*self.height_range)
|
249 |
+
other_viewpoint_position = other_nav_point + other_viewpoint_height * habitat_sim.geo.UP
|
250 |
+
|
251 |
+
# Set viewing direction towards the central point
|
252 |
+
rotation, position = look_at_for_habitat(eye=other_viewpoint_position, center=observed_point, up=habitat_sim.geo.UP, return_cam2world=True)
|
253 |
+
rotation = rotation * generate_orientation_noise(self.pan_range, self.tilt_range, self.roll_range)
|
254 |
+
return position, rotation, other_nav_point
|
255 |
+
|
256 |
+
def is_other_pointcloud_overlapping(self, ref_pointcloud, other_pointcloud):
|
257 |
+
""" Check if a viewpoint is valid and overlaps significantly with a reference one. """
|
258 |
+
# Observation
|
259 |
+
pixels_count = self.resolution[0] * self.resolution[1]
|
260 |
+
valid_fraction = len(other_pointcloud) / pixels_count
|
261 |
+
assert valid_fraction <= 1.0 and valid_fraction >= 0.0
|
262 |
+
overlap = compute_pointcloud_overlaps_scikit(ref_pointcloud, other_pointcloud, self.distance_threshold, compute_symmetric=True)
|
263 |
+
covisibility = min(overlap["intersection1"] / pixels_count, overlap["intersection2"] / pixels_count)
|
264 |
+
is_valid = (valid_fraction >= self.minimum_valid_fraction) and (covisibility >= self.minimum_covisibility)
|
265 |
+
return is_valid, valid_fraction, covisibility
|
266 |
+
|
267 |
+
def is_other_viewpoint_overlapping(self, ref_pointcloud, observation, position, rotation):
|
268 |
+
""" Check if a viewpoint is valid and overlaps significantly with a reference one. """
|
269 |
+
# Observation
|
270 |
+
other_pointcloud = compute_pointcloud(observation['depth'], self.hfov, position, rotation)
|
271 |
+
return self.is_other_pointcloud_overlapping(ref_pointcloud, other_pointcloud)
|
272 |
+
|
273 |
+
def render_viewpoint(self, viewpoint_position, viewpoint_orientation):
|
274 |
+
agent_state = habitat_sim.AgentState()
|
275 |
+
agent_state.position = viewpoint_position
|
276 |
+
agent_state.rotation = viewpoint_orientation
|
277 |
+
self.agent.set_state(agent_state)
|
278 |
+
viewpoint_observations = self.sim.get_sensor_observations(agent_ids=0)
|
279 |
+
_append_camera_parameters(viewpoint_observations, self.hfov, viewpoint_position, viewpoint_orientation)
|
280 |
+
return viewpoint_observations
|
281 |
+
|
282 |
+
def __getitem__(self, useless_idx):
|
283 |
+
ref_position, ref_orientation, nav_point = self.sample_random_viewpoint()
|
284 |
+
ref_observations = self.render_viewpoint(ref_position, ref_orientation)
|
285 |
+
# Extract point cloud
|
286 |
+
ref_pointcloud = compute_pointcloud(depthmap=ref_observations['depth'], hfov=self.hfov,
|
287 |
+
camera_position=ref_position, camera_rotation=ref_orientation)
|
288 |
+
|
289 |
+
pixels_count = self.resolution[0] * self.resolution[1]
|
290 |
+
ref_valid_fraction = len(ref_pointcloud) / pixels_count
|
291 |
+
assert ref_valid_fraction <= 1.0 and ref_valid_fraction >= 0.0
|
292 |
+
if ref_valid_fraction < self.minimum_valid_fraction:
|
293 |
+
# This should produce a recursion error at some point when something is very wrong.
|
294 |
+
return self[0]
|
295 |
+
# Pick an reference observed point in the point cloud
|
296 |
+
observed_point = np.mean(ref_pointcloud, axis=0)
|
297 |
+
|
298 |
+
# Add the first image as reference
|
299 |
+
viewpoints_observations = [ref_observations]
|
300 |
+
viewpoints_covisibility = [ref_valid_fraction]
|
301 |
+
viewpoints_positions = [ref_position]
|
302 |
+
viewpoints_orientations = [quaternion.as_float_array(ref_orientation)]
|
303 |
+
viewpoints_clouds = [ref_pointcloud]
|
304 |
+
viewpoints_valid_fractions = [ref_valid_fraction]
|
305 |
+
|
306 |
+
for _ in range(self.views_count - 1):
|
307 |
+
# Generate an other viewpoint using some dummy random walk
|
308 |
+
successful_sampling = False
|
309 |
+
for sampling_attempt in range(self.max_attempts_count):
|
310 |
+
position, rotation, _ = self.sample_other_random_viewpoint(observed_point, nav_point)
|
311 |
+
# Observation
|
312 |
+
other_viewpoint_observations = self.render_viewpoint(position, rotation)
|
313 |
+
other_pointcloud = compute_pointcloud(other_viewpoint_observations['depth'], self.hfov, position, rotation)
|
314 |
+
|
315 |
+
is_valid, valid_fraction, covisibility = self.is_other_pointcloud_overlapping(ref_pointcloud, other_pointcloud)
|
316 |
+
if is_valid:
|
317 |
+
successful_sampling = True
|
318 |
+
break
|
319 |
+
if not successful_sampling:
|
320 |
+
print("WARNING: Maximum number of attempts reached.")
|
321 |
+
# Dirty hack, try using a novel original viewpoint
|
322 |
+
return self[0]
|
323 |
+
viewpoints_observations.append(other_viewpoint_observations)
|
324 |
+
viewpoints_covisibility.append(covisibility)
|
325 |
+
viewpoints_positions.append(position)
|
326 |
+
viewpoints_orientations.append(quaternion.as_float_array(rotation)) # WXYZ convention for the quaternion encoding.
|
327 |
+
viewpoints_clouds.append(other_pointcloud)
|
328 |
+
viewpoints_valid_fractions.append(valid_fraction)
|
329 |
+
|
330 |
+
# Estimate relations between all pairs of images
|
331 |
+
pairwise_visibility_ratios = np.ones((len(viewpoints_observations), len(viewpoints_observations)))
|
332 |
+
for i in range(len(viewpoints_observations)):
|
333 |
+
pairwise_visibility_ratios[i,i] = viewpoints_valid_fractions[i]
|
334 |
+
for j in range(i+1, len(viewpoints_observations)):
|
335 |
+
overlap = compute_pointcloud_overlaps_scikit(viewpoints_clouds[i], viewpoints_clouds[j], self.distance_threshold, compute_symmetric=True)
|
336 |
+
pairwise_visibility_ratios[i,j] = overlap['intersection1'] / pixels_count
|
337 |
+
pairwise_visibility_ratios[j,i] = overlap['intersection2'] / pixels_count
|
338 |
+
|
339 |
+
# IoU is relative to the image 0
|
340 |
+
data = {"observations": viewpoints_observations,
|
341 |
+
"positions": np.asarray(viewpoints_positions),
|
342 |
+
"orientations": np.asarray(viewpoints_orientations),
|
343 |
+
"covisibility_ratios": np.asarray(viewpoints_covisibility),
|
344 |
+
"valid_fractions": np.asarray(viewpoints_valid_fractions, dtype=float),
|
345 |
+
"pairwise_visibility_ratios": np.asarray(pairwise_visibility_ratios, dtype=float),
|
346 |
+
}
|
347 |
+
|
348 |
+
if self.transform is not None:
|
349 |
+
data = self.transform(data)
|
350 |
+
return data
|
351 |
+
|
352 |
+
def generate_random_spiral_trajectory(self, images_count = 100, max_radius=0.5, half_turns=5, use_constant_orientation=False):
|
353 |
+
"""
|
354 |
+
Return a list of images corresponding to a spiral trajectory from a random starting point.
|
355 |
+
Useful to generate nice visualisations.
|
356 |
+
Use an even number of half turns to get a nice "C1-continuous" loop effect
|
357 |
+
"""
|
358 |
+
ref_position, ref_orientation, navpoint = self.sample_random_viewpoint()
|
359 |
+
ref_observations = self.render_viewpoint(ref_position, ref_orientation)
|
360 |
+
ref_pointcloud = compute_pointcloud(depthmap=ref_observations['depth'], hfov=self.hfov,
|
361 |
+
camera_position=ref_position, camera_rotation=ref_orientation)
|
362 |
+
pixels_count = self.resolution[0] * self.resolution[1]
|
363 |
+
if len(ref_pointcloud) / pixels_count < self.minimum_valid_fraction:
|
364 |
+
# Dirty hack: ensure that the valid part of the image is significant
|
365 |
+
return self.generate_random_spiral_trajectory(images_count, max_radius, half_turns, use_constant_orientation)
|
366 |
+
|
367 |
+
# Pick an observed point in the point cloud
|
368 |
+
observed_point = np.mean(ref_pointcloud, axis=0)
|
369 |
+
ref_R, ref_t = compute_camera_pose_opencv_convention(ref_position, ref_orientation)
|
370 |
+
|
371 |
+
images = []
|
372 |
+
is_valid = []
|
373 |
+
# Spiral trajectory, use_constant orientation
|
374 |
+
for i, alpha in enumerate(np.linspace(0, 1, images_count)):
|
375 |
+
r = max_radius * np.abs(np.sin(alpha * np.pi)) # Increase then decrease the radius
|
376 |
+
theta = alpha * half_turns * np.pi
|
377 |
+
x = r * np.cos(theta)
|
378 |
+
y = r * np.sin(theta)
|
379 |
+
z = 0.0
|
380 |
+
position = ref_position + (ref_R @ np.asarray([x, y, z]).reshape(3,1)).flatten()
|
381 |
+
if use_constant_orientation:
|
382 |
+
orientation = ref_orientation
|
383 |
+
else:
|
384 |
+
# trajectory looking at a mean point in front of the ref observation
|
385 |
+
orientation, position = look_at_for_habitat(eye=position, center=observed_point, up=habitat_sim.geo.UP)
|
386 |
+
observations = self.render_viewpoint(position, orientation)
|
387 |
+
images.append(observations['color'][...,:3])
|
388 |
+
_is_valid, valid_fraction, iou = self.is_other_viewpoint_overlapping(ref_pointcloud, observations, position, orientation)
|
389 |
+
is_valid.append(_is_valid)
|
390 |
+
return images, np.all(is_valid)
|
third_party/mast3r/dust3r/croco/datasets/habitat_sim/pack_metadata_files.py
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2022-present Naver Corporation. All rights reserved.
|
2 |
+
# Licensed under CC BY-NC-SA 4.0 (non-commercial use only).
|
3 |
+
"""
|
4 |
+
Utility script to pack metadata files of the dataset in order to be able to re-generate it elsewhere.
|
5 |
+
"""
|
6 |
+
import os
|
7 |
+
import glob
|
8 |
+
from tqdm import tqdm
|
9 |
+
import shutil
|
10 |
+
import json
|
11 |
+
from datasets.habitat_sim.paths import *
|
12 |
+
import argparse
|
13 |
+
import collections
|
14 |
+
|
15 |
+
if __name__ == "__main__":
|
16 |
+
parser = argparse.ArgumentParser()
|
17 |
+
parser.add_argument("input_dir")
|
18 |
+
parser.add_argument("output_dir")
|
19 |
+
args = parser.parse_args()
|
20 |
+
|
21 |
+
input_dirname = args.input_dir
|
22 |
+
output_dirname = args.output_dir
|
23 |
+
|
24 |
+
input_metadata_filenames = glob.iglob(f"{input_dirname}/**/metadata.json", recursive=True)
|
25 |
+
|
26 |
+
images_count = collections.defaultdict(lambda : 0)
|
27 |
+
|
28 |
+
os.makedirs(output_dirname)
|
29 |
+
for input_filename in tqdm(input_metadata_filenames):
|
30 |
+
# Ignore empty files
|
31 |
+
with open(input_filename, "r") as f:
|
32 |
+
original_metadata = json.load(f)
|
33 |
+
if "multiviews" not in original_metadata or len(original_metadata["multiviews"]) == 0:
|
34 |
+
print("No views in", input_filename)
|
35 |
+
continue
|
36 |
+
|
37 |
+
relpath = os.path.relpath(input_filename, input_dirname)
|
38 |
+
print(relpath)
|
39 |
+
|
40 |
+
# Copy metadata, while replacing scene paths by generic keys depending on the dataset, for portability.
|
41 |
+
# Data paths are sorted by decreasing length to avoid potential bugs due to paths starting by the same string pattern.
|
42 |
+
scenes_dataset_paths = dict(sorted(SCENES_DATASET.items(), key=lambda x: len(x[1]), reverse=True))
|
43 |
+
metadata = dict()
|
44 |
+
for key, value in original_metadata.items():
|
45 |
+
if key in ("scene_dataset_config_file", "scene", "navmesh") and value != "":
|
46 |
+
known_path = False
|
47 |
+
for dataset, dataset_path in scenes_dataset_paths.items():
|
48 |
+
if value.startswith(dataset_path):
|
49 |
+
value = os.path.join(dataset, os.path.relpath(value, dataset_path))
|
50 |
+
known_path = True
|
51 |
+
break
|
52 |
+
if not known_path:
|
53 |
+
raise KeyError("Unknown path:" + value)
|
54 |
+
metadata[key] = value
|
55 |
+
|
56 |
+
# Compile some general statistics while packing data
|
57 |
+
scene_split = metadata["scene"].split("/")
|
58 |
+
upper_level = "/".join(scene_split[:2]) if scene_split[0] == "hm3d" else scene_split[0]
|
59 |
+
images_count[upper_level] += len(metadata["multiviews"])
|
60 |
+
|
61 |
+
output_filename = os.path.join(output_dirname, relpath)
|
62 |
+
os.makedirs(os.path.dirname(output_filename), exist_ok=True)
|
63 |
+
with open(output_filename, "w") as f:
|
64 |
+
json.dump(metadata, f)
|
65 |
+
|
66 |
+
# Print statistics
|
67 |
+
print("Images count:")
|
68 |
+
for upper_level, count in images_count.items():
|
69 |
+
print(f"- {upper_level}: {count}")
|