Spaces:
Running
on
L40S
Running
on
L40S
Upload folder using huggingface_hub
Browse files- third_party/dust3r/assets/demo.jpg +0 -0
- third_party/dust3r/assets/dust3r.jpg +0 -0
- third_party/dust3r/assets/dust3r_archi.jpg +0 -0
- third_party/dust3r/assets/matching.jpg +0 -0
- third_party/dust3r/assets/pipeline1.jpg +0 -0
- third_party/dust3r/croco/assets/Chateau1.png +0 -0
- third_party/dust3r/croco/assets/Chateau2.png +0 -0
- third_party/dust3r/croco/assets/arch.jpg +0 -0
- third_party/dust3r_utils.py +0 -1
- third_party/gen_baking.py +9 -25
- third_party/mesh_baker.py +62 -35
third_party/dust3r/assets/demo.jpg
ADDED
![]() |
third_party/dust3r/assets/dust3r.jpg
ADDED
![]() |
third_party/dust3r/assets/dust3r_archi.jpg
ADDED
![]() |
third_party/dust3r/assets/matching.jpg
ADDED
![]() |
third_party/dust3r/assets/pipeline1.jpg
ADDED
![]() |
third_party/dust3r/croco/assets/Chateau1.png
ADDED
![]() |
third_party/dust3r/croco/assets/Chateau2.png
ADDED
![]() |
third_party/dust3r/croco/assets/arch.jpg
ADDED
![]() |
third_party/dust3r_utils.py
CHANGED
@@ -135,7 +135,6 @@ def infer_match(images, model, vis=False, niter=300, lr=0.01, schedule='cosine',
|
|
135 |
plt.plot([x0, x1 + W0], [y0, y1], '-+', color=cmap(i / (n_viz - 1)), scalex=False, scaley=False)
|
136 |
plt.show(block=True)
|
137 |
|
138 |
-
matches_im0 = remap_points(images[0].shape, matches_im0)
|
139 |
matches_im1 = remap_points(images[1].shape, matches_im1)
|
140 |
return matches_im0, matches_im1
|
141 |
|
|
|
135 |
plt.plot([x0, x1 + W0], [y0, y1], '-+', color=cmap(i / (n_viz - 1)), scalex=False, scaley=False)
|
136 |
plt.show(block=True)
|
137 |
|
|
|
138 |
matches_im1 = remap_points(images[1].shape, matches_im1)
|
139 |
return matches_im0, matches_im1
|
140 |
|
third_party/gen_baking.py
CHANGED
@@ -55,27 +55,17 @@ def load_objs_as_meshes_fast(
|
|
55 |
path_manager: Optional[PathManager] = None,
|
56 |
):
|
57 |
tex = None
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
if tex_maps is not None and len(tex_maps) > 0:
|
65 |
-
verts_uvs = aux.verts_uvs.to(device) # (V, 2)
|
66 |
-
faces_uvs = faces.textures_idx.to(device) # (F, 3)
|
67 |
-
image = list(tex_maps.values())[0].to(device)[None]
|
68 |
-
tex = TexturesUV(verts_uvs=[verts_uvs], faces_uvs=[faces_uvs], maps=image)
|
69 |
mesh = Meshes( verts=[verts.to(device)], faces=[faces.verts_idx.to(device)], textures=tex)
|
70 |
return mesh
|
71 |
|
72 |
|
73 |
def get_triangle_to_triangle(tri_1, tri_2, img_refined):
|
74 |
-
'''
|
75 |
-
args:
|
76 |
-
tri_1:
|
77 |
-
tri_2:
|
78 |
-
'''
|
79 |
r1 = cv2.boundingRect(tri_1)
|
80 |
r2 = cv2.boundingRect(tri_2)
|
81 |
|
@@ -115,11 +105,8 @@ def back_projection(
|
|
115 |
erode_scale=1/100.0,
|
116 |
device="cuda:0"
|
117 |
):
|
118 |
-
# obj_file:
|
119 |
-
# init_texture_file:
|
120 |
-
# render_resolution 正面视角渲染分辨率
|
121 |
-
# uv_resolution 贴图分辨率
|
122 |
-
# thres:normal threshold
|
123 |
|
124 |
os.makedirs(dst_dir, exist_ok=True)
|
125 |
|
@@ -151,8 +138,6 @@ def back_projection(
|
|
151 |
], dim=-1)
|
152 |
triangle_uvs = np.clip(np.round(np.float32(triangle_uvs.cpu())).astype(np.int64), 0, uv_resolution-1)
|
153 |
|
154 |
-
# import ipdb;ipdb.set_trace()
|
155 |
-
|
156 |
|
157 |
R0, T0 = look_at_view_transform(camera_dist, views[0][0], views[0][1])
|
158 |
|
@@ -197,7 +182,7 @@ def back_projection(
|
|
197 |
|
198 |
# seamlessClone
|
199 |
try:
|
200 |
-
images = cv2.seamlessClone(src, dst, src_mask, center, cv2.NORMAL_CLONE) #
|
201 |
# images = cv2.seamlessClone(src, dst, src_mask, center, cv2.MIXED_CLONE)
|
202 |
except Exception as err:
|
203 |
print(f"\n\n Warning seamlessClone error: {err} \n\n")
|
@@ -225,7 +210,6 @@ def back_projection(
|
|
225 |
|
226 |
t0 = time.time()
|
227 |
|
228 |
-
|
229 |
SOFT_NORM = True # process big angle-diff face, true:flase? coeff:skip
|
230 |
|
231 |
for k in faces_covered:
|
|
|
55 |
path_manager: Optional[PathManager] = None,
|
56 |
):
|
57 |
tex = None
|
58 |
+
tex_maps = aux.texture_images
|
59 |
+
if tex_maps is not None and len(tex_maps) > 0:
|
60 |
+
verts_uvs = aux.verts_uvs.to(device) # (V, 2)
|
61 |
+
faces_uvs = faces.textures_idx.to(device) # (F, 3)
|
62 |
+
image = list(tex_maps.values())[0].to(device)[None]
|
63 |
+
tex = TexturesUV(verts_uvs=[verts_uvs], faces_uvs=[faces_uvs], maps=image)
|
|
|
|
|
|
|
|
|
|
|
64 |
mesh = Meshes( verts=[verts.to(device)], faces=[faces.verts_idx.to(device)], textures=tex)
|
65 |
return mesh
|
66 |
|
67 |
|
68 |
def get_triangle_to_triangle(tri_1, tri_2, img_refined):
|
|
|
|
|
|
|
|
|
|
|
69 |
r1 = cv2.boundingRect(tri_1)
|
70 |
r2 = cv2.boundingRect(tri_2)
|
71 |
|
|
|
105 |
erode_scale=1/100.0,
|
106 |
device="cuda:0"
|
107 |
):
|
108 |
+
# obj_file: obj with uv
|
109 |
+
# init_texture_file: uv texture image
|
|
|
|
|
|
|
110 |
|
111 |
os.makedirs(dst_dir, exist_ok=True)
|
112 |
|
|
|
138 |
], dim=-1)
|
139 |
triangle_uvs = np.clip(np.round(np.float32(triangle_uvs.cpu())).astype(np.int64), 0, uv_resolution-1)
|
140 |
|
|
|
|
|
141 |
|
142 |
R0, T0 = look_at_view_transform(camera_dist, views[0][0], views[0][1])
|
143 |
|
|
|
182 |
|
183 |
# seamlessClone
|
184 |
try:
|
185 |
+
images = cv2.seamlessClone(src, dst, src_mask, center, cv2.NORMAL_CLONE) # better
|
186 |
# images = cv2.seamlessClone(src, dst, src_mask, center, cv2.MIXED_CLONE)
|
187 |
except Exception as err:
|
188 |
print(f"\n\n Warning seamlessClone error: {err} \n\n")
|
|
|
210 |
|
211 |
t0 = time.time()
|
212 |
|
|
|
213 |
SOFT_NORM = True # process big angle-diff face, true:flase? coeff:skip
|
214 |
|
215 |
for k in faces_covered:
|
third_party/mesh_baker.py
CHANGED
@@ -25,8 +25,7 @@ class MeshBaker:
|
|
25 |
align_model = "third_party/weights/DUSt3R_ViTLarge_BaseDecoder_512_dpt",
|
26 |
device = "cuda:0",
|
27 |
align_times = 1,
|
28 |
-
iou_thresh = 0.8,
|
29 |
-
force_baking_ele_list = None,
|
30 |
save_memory = False
|
31 |
):
|
32 |
self.device = device
|
@@ -36,8 +35,6 @@ class MeshBaker:
|
|
36 |
self.align_times = align_times
|
37 |
self.align_model.eval()
|
38 |
self.iou_thresh = iou_thresh
|
39 |
-
self.force_baking_ele_list = [] if force_baking_ele_list is None else force_baking_ele_list
|
40 |
-
self.force_baking_ele_list = [int(_) for _ in self.force_baking_ele_list]
|
41 |
set_parameter_grad_false(self.align_model)
|
42 |
print('baking align model', get_parameter_number(self.align_model))
|
43 |
|
@@ -75,7 +72,7 @@ class MeshBaker:
|
|
75 |
torch.cuda.empty_cache()
|
76 |
return res
|
77 |
|
78 |
-
def call(self, save_folder):
|
79 |
obj_path = os.path.join(save_folder, "mesh.obj")
|
80 |
raw_texture_path = os.path.join(save_folder, "texture.png")
|
81 |
views_pil = os.path.join(save_folder, "views.jpg")
|
@@ -93,46 +90,76 @@ class MeshBaker:
|
|
93 |
cond_pil, views = views[0], views[1:]
|
94 |
else:
|
95 |
raise FileNotFoundError("views file not found")
|
96 |
-
|
97 |
-
rendered_views = render_func(obj_path, elev=0, n_views=2)
|
98 |
|
99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
|
101 |
if ele == 0:
|
102 |
-
|
103 |
-
|
|
|
|
|
|
|
|
|
|
|
104 |
|
105 |
-
|
106 |
-
|
|
|
|
|
|
|
107 |
|
108 |
-
if info['mask_iou'] < cond_info['mask_iou']:
|
109 |
-
print("
|
110 |
-
aligned_img = aligned_cond
|
111 |
-
|
112 |
need_baking = info['mask_iou'] > self.iou_thresh
|
|
|
113 |
else:
|
114 |
-
aligned_img, info, need_baking = self.align_and_check(views[ele//60], rendered_views[
|
|
|
115 |
aligned_img.save(save_folder + f'/aligned_{ele}.jpg')
|
116 |
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
|
|
|
|
|
|
|
|
134 |
|
135 |
-
print("
|
136 |
return obj_path
|
137 |
|
138 |
|
|
|
25 |
align_model = "third_party/weights/DUSt3R_ViTLarge_BaseDecoder_512_dpt",
|
26 |
device = "cuda:0",
|
27 |
align_times = 1,
|
28 |
+
iou_thresh = 0.8,
|
|
|
29 |
save_memory = False
|
30 |
):
|
31 |
self.device = device
|
|
|
35 |
self.align_times = align_times
|
36 |
self.align_model.eval()
|
37 |
self.iou_thresh = iou_thresh
|
|
|
|
|
38 |
set_parameter_grad_false(self.align_model)
|
39 |
print('baking align model', get_parameter_number(self.align_model))
|
40 |
|
|
|
72 |
torch.cuda.empty_cache()
|
73 |
return res
|
74 |
|
75 |
+
def call(self, save_folder, force=False, front='auto', others=['180°'], align_times=3, seed=0):
|
76 |
obj_path = os.path.join(save_folder, "mesh.obj")
|
77 |
raw_texture_path = os.path.join(save_folder, "texture.png")
|
78 |
views_pil = os.path.join(save_folder, "views.jpg")
|
|
|
90 |
cond_pil, views = views[0], views[1:]
|
91 |
else:
|
92 |
raise FileNotFoundError("views file not found")
|
|
|
|
|
93 |
|
94 |
+
others = [int(x.replace("°", "")) for x in others]
|
95 |
+
|
96 |
+
if len(others)==0:
|
97 |
+
rendered_views = render_func(obj_path, elev=0, n_views=1)
|
98 |
+
elif len(others)==1 and others[0]==180:
|
99 |
+
rendered_views = render_func(obj_path, elev=0, n_views=2)
|
100 |
+
else:
|
101 |
+
rendered_views = render_func(obj_path, elev=0, n_views=6)
|
102 |
+
|
103 |
+
print(f"Need baking views are {others}")
|
104 |
+
others = [0] + others
|
105 |
+
|
106 |
+
seed_everything(seed)
|
107 |
+
|
108 |
+
for ele_idx, ele in enumerate([0, 60, 120, 180, 240, 300]):
|
109 |
+
|
110 |
+
if ele not in others: continue
|
111 |
+
|
112 |
+
print(f"\n Baking view ele_{ele} ...")
|
113 |
|
114 |
if ele == 0:
|
115 |
+
if front == 'multi-view front view' or front == 'auto':
|
116 |
+
aligned_cond, cond_info, _ = self.align_and_check(cond_pil, rendered_views[0], align_times=self.align_times)
|
117 |
+
if cond_info is None: continue
|
118 |
+
aligned_cond.convert("RGB").save(save_folder + f'/aligned_cond.jpg')
|
119 |
+
if front == 'multi-view front view':
|
120 |
+
aligned_img, info = aligned_cond, cond_info
|
121 |
+
print("Using Cond Image to bake front view")
|
122 |
|
123 |
+
if front == 'input image' or front == 'auto':
|
124 |
+
aligned_img, info, _ = self.align_and_check(views[0], rendered_views[0], align_times=self.align_times)
|
125 |
+
if info is None: continue
|
126 |
+
aligned_img.save(save_folder + f'/aligned_{ele}.jpg')
|
127 |
+
print("Using Input Image to bake front view")
|
128 |
|
129 |
+
if front == 'auto' and info['mask_iou'] < cond_info['mask_iou']:
|
130 |
+
print("Auto using Cond Image to bake front view")
|
131 |
+
aligned_img, info = aligned_cond, cond_info
|
132 |
+
|
133 |
need_baking = info['mask_iou'] > self.iou_thresh
|
134 |
+
|
135 |
else:
|
136 |
+
aligned_img, info, need_baking = self.align_and_check(views[ele//60], rendered_views[min(ele//60, len(others)-1)])
|
137 |
+
if info is None: continue
|
138 |
aligned_img.save(save_folder + f'/aligned_{ele}.jpg')
|
139 |
|
140 |
+
try:
|
141 |
+
if need_baking or force:
|
142 |
+
st = time.time()
|
143 |
+
view1_res = back_projection(
|
144 |
+
obj_file = obj_path,
|
145 |
+
init_texture_file = raw_texture_path,
|
146 |
+
front_view_file = aligned_img,
|
147 |
+
dst_dir = os.path.join(save_folder, f"view_{ele_idx}"),
|
148 |
+
render_resolution = aligned_img.size[0],
|
149 |
+
uv_resolution = 1024,
|
150 |
+
views = [[0, ele]],
|
151 |
+
device = self.device
|
152 |
+
)
|
153 |
+
print(f"view_{ele_idx} elevation_{ele} baking finished at {time.time() - st}")
|
154 |
+
obj_path = os.path.join(save_folder, f"view_{ele_idx}/bake/mesh.obj")
|
155 |
+
raw_texture_path = os.path.join(save_folder, f"view_{ele_idx}/bake/texture.png")
|
156 |
+
else:
|
157 |
+
print(f"Skip view_{ele_idx} elevation_{ele} baking")
|
158 |
+
except Exception as err:
|
159 |
+
print(err)
|
160 |
+
continue
|
161 |
|
162 |
+
print("\nBaking Finished\n")
|
163 |
return obj_path
|
164 |
|
165 |
|