JianyuanWang commited on
Commit
34d287c
β€’
1 Parent(s): 8866a87
This view is limited to 50 files because it contains too many changes. Β  See raw diff
Files changed (50) hide show
  1. app.py +156 -46
  2. debug_demo.py +31 -0
  3. glbscene.glb +0 -0
  4. requirements.txt +1 -1
  5. {vggsfm β†’ vggsfm_code}/.gitignore +0 -0
  6. {vggsfm β†’ vggsfm_code}/CHANGELOG.txt +0 -0
  7. {vggsfm β†’ vggsfm_code}/CODE_OF_CONDUCT.md +0 -0
  8. {vggsfm β†’ vggsfm_code}/CONTRIBUTING.md +0 -0
  9. {vggsfm β†’ vggsfm_code}/LICENSE.txt +0 -0
  10. {vggsfm β†’ vggsfm_code}/README.md +0 -0
  11. {vggsfm β†’ vggsfm_code}/assets/ui.png +0 -0
  12. {vggsfm β†’ vggsfm_code}/cfgs/demo.yaml +0 -0
  13. {vggsfm β†’ vggsfm_code}/demo.py +0 -0
  14. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000007.jpg +0 -0
  15. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000012.jpg +0 -0
  16. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000017.jpg +0 -0
  17. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000019.jpg +0 -0
  18. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000024.jpg +0 -0
  19. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000025.jpg +0 -0
  20. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000043.jpg +0 -0
  21. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000052.jpg +0 -0
  22. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000070.jpg +0 -0
  23. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000077.jpg +0 -0
  24. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000085.jpg +0 -0
  25. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000096.jpg +0 -0
  26. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000128.jpg +0 -0
  27. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000145.jpg +0 -0
  28. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000160.jpg +0 -0
  29. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000162.jpg +0 -0
  30. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000168.jpg +0 -0
  31. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000172.jpg +0 -0
  32. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000191.jpg +0 -0
  33. {vggsfm β†’ vggsfm_code}/examples/apple/images/frame000200.jpg +0 -0
  34. {vggsfm β†’ vggsfm_code}/examples/british_museum/images/29057984_287139632.jpg +0 -0
  35. {vggsfm β†’ vggsfm_code}/examples/british_museum/images/32630292_7166579210.jpg +0 -0
  36. {vggsfm β†’ vggsfm_code}/examples/british_museum/images/45839934_4117745134.jpg +0 -0
  37. {vggsfm β†’ vggsfm_code}/examples/british_museum/images/51004432_567773767.jpg +0 -0
  38. {vggsfm β†’ vggsfm_code}/examples/british_museum/images/62620282_3728576515.jpg +0 -0
  39. {vggsfm β†’ vggsfm_code}/examples/british_museum/images/71931631_7212707886.jpg +0 -0
  40. {vggsfm β†’ vggsfm_code}/examples/british_museum/images/78600497_407639599.jpg +0 -0
  41. {vggsfm β†’ vggsfm_code}/examples/british_museum/images/80340357_5029510336.jpg +0 -0
  42. {vggsfm β†’ vggsfm_code}/examples/british_museum/images/81272348_2712949069.jpg +0 -0
  43. {vggsfm β†’ vggsfm_code}/examples/british_museum/images/93266801_2335569192.jpg +0 -0
  44. {vggsfm β†’ vggsfm_code}/examples/cake/images/frame000020.jpg +0 -0
  45. {vggsfm β†’ vggsfm_code}/examples/cake/images/frame000069.jpg +0 -0
  46. {vggsfm β†’ vggsfm_code}/examples/cake/images/frame000096.jpg +0 -0
  47. {vggsfm β†’ vggsfm_code}/examples/cake/images/frame000112.jpg +0 -0
  48. {vggsfm β†’ vggsfm_code}/examples/cake/images/frame000146.jpg +0 -0
  49. {vggsfm β†’ vggsfm_code}/examples/cake/images/frame000149.jpg +0 -0
  50. {vggsfm β†’ vggsfm_code}/examples/cake/images/frame000166.jpg +0 -0
app.py CHANGED
@@ -4,68 +4,178 @@ import torch
4
  import numpy as np
5
  import gradio as gr
6
 
 
 
 
7
 
 
 
8
 
9
- def parse_video(video_file):
10
- vs = cv2.VideoCapture(video_file)
11
-
12
- frames = []
13
- while True:
14
- (gotit, frame) = vs.read()
15
- if frame is not None:
16
- frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
17
- frames.append(frame)
18
- if not gotit:
19
- break
20
 
21
- return np.stack(frames)
 
 
22
 
23
 
 
24
 
25
  @spaces.GPU
26
- def cotracker_demo(
 
27
  input_video,
28
- grid_size: int = 10,
29
- tracks_leave_trace: bool = False,
 
30
  ):
31
- load_video = parse_video(input_video)
32
- load_video = torch.from_numpy(load_video).permute(0, 3, 1, 2)[None].float()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- import time
35
 
36
- def current_milli_time():
37
- return round(time.time() * 1000)
38
 
39
- filename = str(current_milli_time())
 
 
 
 
 
40
 
41
- return os.path.join(
42
- os.path.dirname(__file__), "results", f"{filename}.mp4"
43
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
 
 
 
 
 
45
 
 
46
 
 
 
 
47
 
 
 
48
 
49
- app = gr.Interface(
50
- title="🎨 CoTracker: It is Better to Track Together",
51
- description="<div style='text-align: left;'> \
52
- <p>Welcome to <a href='http://co-tracker.github.io' target='_blank'>CoTracker</a>! This space demonstrates point (pixel) tracking in videos. \
53
- Points are sampled on a regular grid and are tracked jointly. </p> \
54
- <p> To get started, simply upload your <b>.mp4</b> video in landscape orientation or click on one of the example videos to load them. The shorter the video, the faster the processing. We recommend submitting short videos of length <b>2-7 seconds</b>.</p> \
55
- <ul style='display: inline-block; text-align: left;'> \
56
- <li>The total number of grid points is the square of <b>Grid Size</b>.</li> \
57
- <li>Check <b>Visualize Track Traces</b> to visualize traces of all the tracked points. </li> \
58
- </ul> \
59
- <p style='text-align: left'>For more details, check out our <a href='https://github.com/facebookresearch/co-tracker' target='_blank'>GitHub Repo</a> ⭐</p> \
60
- </div>",
61
- fn=cotracker_demo,
62
- inputs=[
63
- gr.Video(type="file", label="Input video", interactive=True),
64
- gr.Slider(minimum=10, maximum=80, step=1, value=10, label="Number of tracks"),
65
- ],
66
- outputs=gr.Video(label="Video with predicted tracks"),
67
- cache_examples=True,
68
- allow_flagging=False,
69
- )
70
- app.queue(max_size=20, concurrency_count=1).launch(debug=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
 
4
  import numpy as np
5
  import gradio as gr
6
 
7
+ import trimesh
8
+ import sys
9
+ import os
10
 
11
+ sys.path.append('vggsfm_code/')
12
+ import shutil
13
 
14
+ from vggsfm_code.hf_demo import demo_fn
15
+ from omegaconf import DictConfig, OmegaConf
16
+ from viz_utils.viz_fn import add_camera
 
 
 
 
 
 
 
 
17
 
18
+ #
19
+ from scipy.spatial.transform import Rotation
20
+ import PIL
21
 
22
 
23
+ import spaces
24
 
25
  @spaces.GPU
26
+ def vggsfm_demo(
27
+ input_image,
28
  input_video,
29
+ query_frame_num,
30
+ max_query_pts
31
+ # grid_size: int = 10,
32
  ):
33
+ cfg_file = "vggsfm_code/cfgs/demo.yaml"
34
+ cfg = OmegaConf.load(cfg_file)
35
+
36
+ max_input_image = 20
37
+
38
+ target_dir = f"input_images"
39
+ if os.path.exists(target_dir):
40
+ shutil.rmtree(target_dir)
41
+
42
+ os.makedirs(target_dir)
43
+ target_dir_images = target_dir + "/images"
44
+ os.makedirs(target_dir_images)
45
+
46
+ if input_image is not None:
47
+ if len(input_image)<3:
48
+ return None, "Please input at least three frames"
49
+
50
+ input_image = sorted(input_image)
51
+ input_image = input_image[:max_input_image]
52
+
53
+ # Copy files to the new directory
54
+ for file_name in input_image:
55
+ shutil.copy(file_name, target_dir_images)
56
+ elif input_video is not None:
57
+ vs = cv2.VideoCapture(input_video)
58
+
59
+ fps = vs.get(cv2.CAP_PROP_FPS)
60
+
61
+ frame_rate = 1
62
+ frame_interval = int(fps * frame_rate)
63
+
64
+ video_frame_num = 0
65
+ count = 0
66
+
67
+ while video_frame_num<=max_input_image:
68
+ (gotit, frame) = vs.read()
69
+ count +=1
70
+
71
+ if count % frame_interval == 0:
72
+ cv2.imwrite(target_dir_images+"/"+f"{video_frame_num:06}.png", frame)
73
+ video_frame_num+=1
74
+ if not gotit:
75
+ break
76
+ if video_frame_num<3:
77
+ return None, "Please input at least three frames"
78
+ else:
79
+ return None, "Input format incorrect"
80
+
81
+ cfg.query_frame_num = query_frame_num
82
+ cfg.max_query_pts = max_query_pts
83
+ print(f"Files have been copied to {target_dir_images}")
84
+ cfg.SCENE_DIR = target_dir
85
+
86
+ predictions = demo_fn(cfg)
87
+
88
+ glbfile = vggsfm_predictions_to_glb(predictions)
89
+
90
+
91
+ print(input_image)
92
+ print(input_video)
93
+ return glbfile, "Success"
94
 
 
95
 
 
 
96
 
97
+
98
+ def vggsfm_predictions_to_glb(predictions):
99
+ # learned from https://github.com/naver/dust3r/blob/main/dust3r/viz.py
100
+ points3D = predictions["points3D"].cpu().numpy()
101
+ points3D_rgb = predictions["points3D_rgb"].cpu().numpy()
102
+ points3D_rgb = (points3D_rgb*255).astype(np.uint8)
103
 
104
+ extrinsics_opencv = predictions["extrinsics_opencv"].cpu().numpy()
105
+ intrinsics_opencv = predictions["intrinsics_opencv"].cpu().numpy()
106
+ raw_image_paths = predictions["raw_image_paths"]
107
+ images = predictions["images"].permute(0,2,3,1).cpu().numpy()
108
+ images = (images*255).astype(np.uint8)
109
+
110
+ glbscene = trimesh.Scene()
111
+ point_cloud = trimesh.PointCloud(points3D, colors=points3D_rgb)
112
+ glbscene.add_geometry(point_cloud)
113
+
114
+
115
+ camera_edge_colors = [(255, 0, 0), (0, 0, 255), (0, 255, 0), (255, 0, 255), (255, 204, 0), (0, 204, 204),
116
+ (128, 255, 255), (255, 128, 255), (255, 255, 128), (0, 0, 0), (128, 128, 128)]
117
+
118
+ frame_num = len(extrinsics_opencv)
119
+ extrinsics_opencv_4x4 = np.zeros((frame_num, 4, 4))
120
+ extrinsics_opencv_4x4[:, :3, :4] = extrinsics_opencv
121
+ extrinsics_opencv_4x4[:, 3, 3] = 1
122
 
123
+ for idx in range(frame_num):
124
+ cam_from_world = extrinsics_opencv_4x4[idx]
125
+ cam_to_world = np.linalg.inv(cam_from_world)
126
+ cur_cam_color = camera_edge_colors[idx % len(camera_edge_colors)]
127
+ cur_focal = intrinsics_opencv[idx, 0, 0]
128
 
129
+ # cur_image_path = raw_image_paths[idx]
130
 
131
+ # cur_image = np.array(PIL.Image.open(cur_image_path))
132
+ # add_camera(glbscene, cam_to_world, cur_cam_color, image=None, imsize=cur_image.shape[1::-1],
133
+ # focal=None,screen_width=0.3)
134
 
135
+ add_camera(glbscene, cam_to_world, cur_cam_color, image=None, imsize=(1024,1024),
136
+ focal=None,screen_width=0.35)
137
 
138
+ opengl_mat = np.array([[1, 0, 0, 0],
139
+ [0, -1, 0, 0],
140
+ [0, 0, -1, 0],
141
+ [0, 0, 0, 1]])
142
+
143
+ rot = np.eye(4)
144
+ rot[:3, :3] = Rotation.from_euler('y', np.deg2rad(180)).as_matrix()
145
+ glbscene.apply_transform(np.linalg.inv(np.linalg.inv(extrinsics_opencv_4x4[0]) @ opengl_mat @ rot))
146
+
147
+ glbfile = "glbscene.glb"
148
+ glbscene.export(file_obj=glbfile)
149
+ return glbfile
150
+
151
+
152
+
153
+
154
+
155
+ if True:
156
+ demo = gr.Interface(
157
+ title="🎨 VGGSfM: Visual Geometry Grounded Deep Structure From Motion",
158
+ description="<div style='text-align: left;'> \
159
+ <p>Welcome to <a href='https://github.com/facebookresearch/vggsfm' target='_blank'>VGGSfM</a>!",
160
+ fn=vggsfm_demo,
161
+ inputs=[
162
+ gr.File(file_count="multiple", label="Input Images", interactive=True),
163
+ gr.Video(label="Input video", interactive=True),
164
+ gr.Slider(minimum=1, maximum=10, step=1, value=5, label="Number of query images"),
165
+ gr.Slider(minimum=512, maximum=4096, step=1, value=1024, label="Number of query points"),
166
+ ],
167
+ outputs=[gr.Model3D(label="Reconstruction"), gr.Textbox(label="Log")],
168
+ cache_examples=True,
169
+ allow_flagging=False,
170
+ )
171
+ demo.queue(max_size=20, concurrency_count=1).launch(debug=True)
172
+
173
+ # demo.launch(debug=True, share=True)
174
+ else:
175
+ import glob
176
+ files = glob.glob(f'vggsfm_code/examples/cake/images/*', recursive=True)
177
+ vggsfm_demo(files, None, None)
178
+
179
+
180
+ # demo.queue(max_size=20, concurrency_count=1).launch(debug=True, share=True)
181
 
debug_demo.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+
3
+ def greet(name, intensity):
4
+ return "Hello, " + name + "!" * int(intensity)
5
+
6
+ demo = gr.Interface(
7
+ fn=greet,
8
+ inputs=["text", "slider"],
9
+ outputs=["text"],
10
+ )
11
+
12
+ demo.launch(share=True)
13
+
14
+
15
+ import sys
16
+ import os
17
+
18
+ sys.path.append('vggsfm_code/')
19
+
20
+ from vggsfm_code.hf_demo import demo_fn
21
+ from omegaconf import DictConfig, OmegaConf
22
+
23
+ cfg_file = "vggsfm_code/cfgs/demo.yaml"
24
+ cfg = OmegaConf.load(cfg_file)
25
+ cfg.SCENE_DIR = "vggsfm_code/examples/cake"
26
+
27
+ import pdb;pdb.set_trace()
28
+
29
+ demo_fn(cfg)
30
+
31
+
glbscene.glb ADDED
Binary file (97.8 kB). View file
 
requirements.txt CHANGED
@@ -7,4 +7,4 @@ git+https://github.com/cvg/LightGlue.git#egg=LightGlue
7
  numpy==1.26.3
8
  pycolmap==0.6.1
9
  https://huggingface.co/facebook/VGGSfM/resolve/main/poselib-2.0.2-cp310-cp310-linux_x86_64.whl
10
-
 
7
  numpy==1.26.3
8
  pycolmap==0.6.1
9
  https://huggingface.co/facebook/VGGSfM/resolve/main/poselib-2.0.2-cp310-cp310-linux_x86_64.whl
10
+ trimesh
{vggsfm β†’ vggsfm_code}/.gitignore RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/CHANGELOG.txt RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/CODE_OF_CONDUCT.md RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/CONTRIBUTING.md RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/LICENSE.txt RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/README.md RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/assets/ui.png RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/cfgs/demo.yaml RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/demo.py RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000007.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000012.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000017.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000019.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000024.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000025.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000043.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000052.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000070.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000077.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000085.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000096.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000128.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000145.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000160.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000162.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000168.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000172.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000191.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/apple/images/frame000200.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/british_museum/images/29057984_287139632.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/british_museum/images/32630292_7166579210.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/british_museum/images/45839934_4117745134.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/british_museum/images/51004432_567773767.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/british_museum/images/62620282_3728576515.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/british_museum/images/71931631_7212707886.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/british_museum/images/78600497_407639599.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/british_museum/images/80340357_5029510336.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/british_museum/images/81272348_2712949069.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/british_museum/images/93266801_2335569192.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/cake/images/frame000020.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/cake/images/frame000069.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/cake/images/frame000096.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/cake/images/frame000112.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/cake/images/frame000146.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/cake/images/frame000149.jpg RENAMED
File without changes
{vggsfm β†’ vggsfm_code}/examples/cake/images/frame000166.jpg RENAMED
File without changes