Spaces:
Running
on
Zero
Running
on
Zero
JianyuanWang
commited on
Commit
•
9a1dda4
1
Parent(s):
b19c7bf
update robust
Browse files- app.py +3 -3
- vggsfm_code/cfgs/demo.yaml +1 -1
- vggsfm_code/vggsfm/utils/triangulation_helpers.py +31 -7
app.py
CHANGED
@@ -205,7 +205,7 @@ with gr.Blocks() as demo:
|
|
205 |
</ul>
|
206 |
<p>If both images and videos are uploaded, the demo will only reconstruct the uploaded images. By default, we extract <strong> 1 image frame per second from the input video </strong>. To prevent crashes on the Hugging Face space, we currently limit reconstruction to the first 25 image frames. </p>
|
207 |
<p>SfM methods are designed for <strong> rigid/static reconstruction </strong>. When dealing with dynamic/moving inputs, these methods may still work by focusing on the rigid parts of the scene. However, to ensure high-quality results, it is better to minimize the presence of moving objects in the input data. </p>
|
208 |
-
<p>The reconstruction should typically take <strong> up to 90 seconds </strong>. If it takes longer, the input data is likely not well-conditioned. </p>
|
209 |
<p>If you meet any problem, feel free to create an issue in our <a href="https://github.com/facebookresearch/vggsfm" target="_blank">GitHub Repo</a> ⭐</p>
|
210 |
<p>(Please note that running reconstruction on Hugging Face space is slower than on a local machine.) </p>
|
211 |
</div>
|
@@ -215,9 +215,9 @@ with gr.Blocks() as demo:
|
|
215 |
with gr.Column(scale=1):
|
216 |
input_video = gr.Video(label="Input video", interactive=True)
|
217 |
input_images = gr.File(file_count="multiple", label="Input Images", interactive=True)
|
218 |
-
num_query_images = gr.Slider(minimum=1, maximum=
|
219 |
info="More query images usually lead to better reconstruction at lower speeds. If the viewpoint differences between your images are minimal, you can set this value to 1. ")
|
220 |
-
num_query_points = gr.Slider(minimum=512, maximum=
|
221 |
info="More query points usually lead to denser reconstruction at lower speeds.")
|
222 |
|
223 |
with gr.Column(scale=3):
|
|
|
205 |
</ul>
|
206 |
<p>If both images and videos are uploaded, the demo will only reconstruct the uploaded images. By default, we extract <strong> 1 image frame per second from the input video </strong>. To prevent crashes on the Hugging Face space, we currently limit reconstruction to the first 25 image frames. </p>
|
207 |
<p>SfM methods are designed for <strong> rigid/static reconstruction </strong>. When dealing with dynamic/moving inputs, these methods may still work by focusing on the rigid parts of the scene. However, to ensure high-quality results, it is better to minimize the presence of moving objects in the input data. </p>
|
208 |
+
<p>The reconstruction should typically take <strong> up to 90 seconds </strong>. If it takes longer, the input data is likely not well-conditioned or the query images/points are set too high. </p>
|
209 |
<p>If you meet any problem, feel free to create an issue in our <a href="https://github.com/facebookresearch/vggsfm" target="_blank">GitHub Repo</a> ⭐</p>
|
210 |
<p>(Please note that running reconstruction on Hugging Face space is slower than on a local machine.) </p>
|
211 |
</div>
|
|
|
215 |
with gr.Column(scale=1):
|
216 |
input_video = gr.Video(label="Input video", interactive=True)
|
217 |
input_images = gr.File(file_count="multiple", label="Input Images", interactive=True)
|
218 |
+
num_query_images = gr.Slider(minimum=1, maximum=10, step=1, value=4, label="Number of query images (key frames)",
|
219 |
info="More query images usually lead to better reconstruction at lower speeds. If the viewpoint differences between your images are minimal, you can set this value to 1. ")
|
220 |
+
num_query_points = gr.Slider(minimum=512, maximum=4096, step=1, value=1024, label="Number of query points",
|
221 |
info="More query points usually lead to denser reconstruction at lower speeds.")
|
222 |
|
223 |
with gr.Column(scale=3):
|
vggsfm_code/cfgs/demo.yaml
CHANGED
@@ -17,7 +17,7 @@ filter_invalid_frame: True
|
|
17 |
comple_nonvis: True
|
18 |
query_frame_num: 3
|
19 |
robust_refine: 2
|
20 |
-
BA_iters:
|
21 |
|
22 |
low_mem: True
|
23 |
|
|
|
17 |
comple_nonvis: True
|
18 |
query_frame_num: 3
|
19 |
robust_refine: 2
|
20 |
+
BA_iters: 1
|
21 |
|
22 |
low_mem: True
|
23 |
|
vggsfm_code/vggsfm/utils/triangulation_helpers.py
CHANGED
@@ -14,7 +14,7 @@ import pycolmap
|
|
14 |
|
15 |
from torch.cuda.amp import autocast
|
16 |
from itertools import combinations
|
17 |
-
|
18 |
|
19 |
def triangulate_multi_view_point_batched(
|
20 |
cams_from_world, points, mask=None, compute_tri_angle=False, check_cheirality=False
|
@@ -44,14 +44,38 @@ def triangulate_multi_view_point_batched(
|
|
44 |
|
45 |
A = torch.einsum("bnij,bnik->bjk", terms, terms)
|
46 |
|
|
|
|
|
47 |
# Compute eigenvalues and eigenvectors
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
_, eigenvectors = torch.linalg.eigh(A)
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
# Select the first eigenvector
|
57 |
first_eigenvector = eigenvectors[:, :, 0]
|
|
|
14 |
|
15 |
from torch.cuda.amp import autocast
|
16 |
from itertools import combinations
|
17 |
+
import math
|
18 |
|
19 |
def triangulate_multi_view_point_batched(
|
20 |
cams_from_world, points, mask=None, compute_tri_angle=False, check_cheirality=False
|
|
|
44 |
|
45 |
A = torch.einsum("bnij,bnik->bjk", terms, terms)
|
46 |
|
47 |
+
|
48 |
+
|
49 |
# Compute eigenvalues and eigenvectors
|
50 |
+
num_A_batch = len(A)
|
51 |
+
MAX_CUSOLVER_STATUS_INVALID_VALUE = 1024000
|
52 |
+
if num_A_batch>MAX_CUSOLVER_STATUS_INVALID_VALUE:
|
53 |
+
print("A too big matrix for torch.linalg.eigh(); Meet CUSOLVER_STATUS_INVALID_VALUE; Make it happy now")
|
54 |
+
num_runs = math.ceil(num_A_batch/MAX_CUSOLVER_STATUS_INVALID_VALUE)
|
55 |
+
eigenvectors_list = []
|
56 |
+
for run_idx in range(num_runs):
|
57 |
+
start_idx = run_idx * MAX_CUSOLVER_STATUS_INVALID_VALUE
|
58 |
+
end_idx = (run_idx+1) * MAX_CUSOLVER_STATUS_INVALID_VALUE
|
59 |
+
_, eigenvectors = torch.linalg.eigh(A[start_idx:end_idx])
|
60 |
+
eigenvectors_list.append(eigenvectors)
|
61 |
+
eigenvectors = torch.cat(eigenvectors_list)
|
62 |
+
else:
|
63 |
_, eigenvectors = torch.linalg.eigh(A)
|
64 |
+
|
65 |
+
|
66 |
+
# try:
|
67 |
+
# _, eigenvectors = torch.linalg.eigh(A)
|
68 |
+
# except:
|
69 |
+
# # _, eigenvectors = torch.linalg.eigh(A[len(A)//10:len(A)//3])
|
70 |
+
# # for idx in
|
71 |
+
# torch.linalg.eigh(A[:len(A)//3])
|
72 |
+
# print("Meet CUSOLVER_STATUS_INVALID_VALUE ERROR during torch.linalg.eigh()")
|
73 |
+
# print("SWITCH TO torch.linalg.eig()")
|
74 |
+
# import pdb;pdb.set_trace()
|
75 |
+
# _, eigenvectors = torch.linalg.eig(A)
|
76 |
+
# eigenvectors = torch.real(eigenvectors)
|
77 |
+
|
78 |
+
|
79 |
|
80 |
# Select the first eigenvector
|
81 |
first_eigenvector = eigenvectors[:, :, 0]
|