Commit
·
9a3d596
1
Parent(s):
eb6226d
Optimize generate3d function for performance and clarity
Browse files- Streamlined the color and coordinate processing by simplifying tensor operations and enhancing readability.
- Improved the handling of denoising logic with clearer condition checks and timing measurements.
- Added debug prints to monitor processing times for unet and UV mapping, aiding in performance analysis.
- inference.py +52 -47
inference.py
CHANGED
@@ -1,55 +1,58 @@
|
|
1 |
import numpy as np
|
2 |
import torch
|
3 |
import time
|
|
|
4 |
from util.utils import get_tri
|
5 |
import tempfile
|
|
|
|
|
6 |
from util.renderer import Renderer
|
7 |
-
|
8 |
-
from PIL import Image
|
9 |
-
import trimesh
|
10 |
-
from scipy.spatial import cKDTree
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
-
def generate3d(model, rgb, ccm, device):
|
14 |
-
model.renderer = Renderer(
|
15 |
-
tet_grid_size=model.tet_grid_size,
|
16 |
-
camera_angle_num=model.camera_angle_num,
|
17 |
-
scale=model.input.scale,
|
18 |
-
geo_type=model.geo_type
|
19 |
-
)
|
20 |
-
|
21 |
-
color_tri = torch.from_numpy(rgb) / 255
|
22 |
-
xyz_tri = torch.from_numpy(ccm[:, :, (2, 1, 0)]) / 255
|
23 |
-
color = color_tri.permute(2, 0, 1)
|
24 |
-
xyz = xyz_tri.permute(2, 0, 1)
|
25 |
|
26 |
def get_imgs(color):
|
|
|
27 |
color_list = []
|
28 |
-
color_list.append(color[
|
29 |
-
for i in range(0,
|
30 |
-
color_list.append(color[
|
31 |
-
return torch.stack(color_list, dim=0)
|
32 |
-
|
33 |
-
triplane_color = get_imgs(color).permute(0,
|
34 |
|
35 |
color = get_imgs(color)
|
36 |
xyz = get_imgs(xyz)
|
37 |
|
38 |
-
color = get_tri(color, dim=0, blender=True, scale=1).unsqueeze(0)
|
39 |
-
xyz = get_tri(xyz, dim=0, blender=True, scale=1, fix=True).unsqueeze(0)
|
40 |
|
41 |
-
triplane = torch.cat([color,
|
|
|
42 |
model.eval()
|
|
|
43 |
|
44 |
-
if model.denoising:
|
45 |
tnew = 20
|
46 |
-
tnew = torch.randint(tnew, tnew
|
47 |
-
noise_new = torch.randn_like(triplane) *
|
48 |
-
triplane = model.scheduler.add_noise(triplane, noise_new, tnew)
|
|
|
49 |
with torch.no_grad():
|
50 |
-
triplane_feature2 = model.unet2(triplane,
|
|
|
|
|
|
|
51 |
else:
|
52 |
triplane_feature2 = model.unet2(triplane)
|
|
|
53 |
|
54 |
with torch.no_grad():
|
55 |
data_config = {
|
@@ -58,8 +61,10 @@ def generate3d(model, rgb, ccm, device):
|
|
58 |
}
|
59 |
|
60 |
verts, faces = model.decode(data_config, triplane_feature2)
|
|
|
61 |
data_config['verts'] = verts[0]
|
62 |
data_config['faces'] = faces
|
|
|
63 |
|
64 |
from kiui.mesh_utils import clean_mesh
|
65 |
verts, faces = clean_mesh(data_config['verts'].squeeze().cpu().numpy().astype(np.float32), data_config['faces'].squeeze().cpu().numpy().astype(np.int32), repair = False, remesh=True, remesh_size=0.005, remesh_iters=1)
|
@@ -70,25 +75,25 @@ def generate3d(model, rgb, ccm, device):
|
|
70 |
with torch.no_grad():
|
71 |
mesh_path_glb = tempfile.NamedTemporaryFile(suffix=f"", delete=False).name
|
72 |
model.export_mesh(data_config, mesh_path_glb, tri_fea_2 = triplane_feature2)
|
73 |
-
# # Build KDTree from original verts
|
74 |
-
# tree = cKDTree(orig_verts)
|
75 |
-
|
76 |
-
# # For each new vertex, find the nearest old vertex and copy its color
|
77 |
-
# k = 3
|
78 |
-
# dists, idxs = tree.query(verts, k=k)
|
79 |
-
# # Use only the nearest neighbor for color assignment
|
80 |
-
# new_colors = orig_colors[idxs[:, 0]]
|
81 |
|
82 |
-
|
83 |
-
|
|
|
84 |
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
|
89 |
-
|
90 |
-
|
|
|
91 |
|
92 |
-
|
|
|
|
|
|
|
93 |
|
94 |
-
|
|
|
|
|
|
|
|
1 |
import numpy as np
|
2 |
import torch
|
3 |
import time
|
4 |
+
import nvdiffrast.torch as dr
|
5 |
from util.utils import get_tri
|
6 |
import tempfile
|
7 |
+
from mesh import Mesh
|
8 |
+
import zipfile
|
9 |
from util.renderer import Renderer
|
10 |
+
def generate3d(model, rgb, ccm, device):
|
|
|
|
|
|
|
11 |
|
12 |
+
model.renderer = Renderer(tet_grid_size=model.tet_grid_size, camera_angle_num=model.camera_angle_num,
|
13 |
+
scale=model.input.scale, geo_type = model.geo_type)
|
14 |
+
|
15 |
+
color_tri = torch.from_numpy(rgb)/255
|
16 |
+
xyz_tri = torch.from_numpy(ccm[:,:,(2,1,0)])/255
|
17 |
+
color = color_tri.permute(2,0,1)
|
18 |
+
xyz = xyz_tri.permute(2,0,1)
|
19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
def get_imgs(color):
|
22 |
+
# color : [C, H, W*6]
|
23 |
color_list = []
|
24 |
+
color_list.append(color[:,:,256*5:256*(1+5)])
|
25 |
+
for i in range(0,5):
|
26 |
+
color_list.append(color[:,:,256*i:256*(1+i)])
|
27 |
+
return torch.stack(color_list, dim=0)# [6, C, H, W]
|
28 |
+
|
29 |
+
triplane_color = get_imgs(color).permute(0,2,3,1).unsqueeze(0).to(device)# [1, 6, H, W, C]
|
30 |
|
31 |
color = get_imgs(color)
|
32 |
xyz = get_imgs(xyz)
|
33 |
|
34 |
+
color = get_tri(color, dim=0, blender= True, scale = 1).unsqueeze(0)
|
35 |
+
xyz = get_tri(xyz, dim=0, blender= True, scale = 1, fix= True).unsqueeze(0)
|
36 |
|
37 |
+
triplane = torch.cat([color,xyz],dim=1).to(device)
|
38 |
+
# 3D visualize
|
39 |
model.eval()
|
40 |
+
|
41 |
|
42 |
+
if model.denoising == True:
|
43 |
tnew = 20
|
44 |
+
tnew = torch.randint(tnew, tnew+1, [triplane.shape[0]], dtype=torch.long, device=triplane.device)
|
45 |
+
noise_new = torch.randn_like(triplane) *0.5+0.5
|
46 |
+
triplane = model.scheduler.add_noise(triplane, noise_new, tnew)
|
47 |
+
start_time = time.time()
|
48 |
with torch.no_grad():
|
49 |
+
triplane_feature2 = model.unet2(triplane,tnew)
|
50 |
+
end_time = time.time()
|
51 |
+
elapsed_time = end_time - start_time
|
52 |
+
print(f"unet takes {elapsed_time}s")
|
53 |
else:
|
54 |
triplane_feature2 = model.unet2(triplane)
|
55 |
+
|
56 |
|
57 |
with torch.no_grad():
|
58 |
data_config = {
|
|
|
61 |
}
|
62 |
|
63 |
verts, faces = model.decode(data_config, triplane_feature2)
|
64 |
+
|
65 |
data_config['verts'] = verts[0]
|
66 |
data_config['faces'] = faces
|
67 |
+
|
68 |
|
69 |
from kiui.mesh_utils import clean_mesh
|
70 |
verts, faces = clean_mesh(data_config['verts'].squeeze().cpu().numpy().astype(np.float32), data_config['faces'].squeeze().cpu().numpy().astype(np.int32), repair = False, remesh=True, remesh_size=0.005, remesh_iters=1)
|
|
|
75 |
with torch.no_grad():
|
76 |
mesh_path_glb = tempfile.NamedTemporaryFile(suffix=f"", delete=False).name
|
77 |
model.export_mesh(data_config, mesh_path_glb, tri_fea_2 = triplane_feature2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
|
79 |
+
# glctx = dr.RasterizeGLContext()#dr.RasterizeCudaContext()
|
80 |
+
# mesh_path_obj = tempfile.NamedTemporaryFile(suffix=f"", delete=False).name
|
81 |
+
# model.export_mesh_wt_uv(glctx, data_config, mesh_path_obj, "", device, res=(1024,1024), tri_fea_2=triplane_feature2)
|
82 |
|
83 |
+
# mesh = Mesh.load(mesh_path_obj+".obj", bound=0.9, front_dir="+z")
|
84 |
+
# mesh_path_glb = tempfile.NamedTemporaryFile(suffix=f"", delete=False).name
|
85 |
+
# mesh.write(mesh_path_glb+".glb")
|
86 |
|
87 |
+
# # mesh_obj2 = trimesh.load(mesh_path_glb+".glb", file_type='glb')
|
88 |
+
# # mesh_path_obj2 = tempfile.NamedTemporaryFile(suffix=f"", delete=False).name
|
89 |
+
# # mesh_obj2.export(mesh_path_obj2+".obj")
|
90 |
|
91 |
+
# with zipfile.ZipFile(mesh_path_obj+'.zip', 'w') as myzip:
|
92 |
+
# myzip.write(mesh_path_obj+'.obj', mesh_path_obj.split("/")[-1]+'.obj')
|
93 |
+
# myzip.write(mesh_path_obj+'.png', mesh_path_obj.split("/")[-1]+'.png')
|
94 |
+
# myzip.write(mesh_path_obj+'.mtl', mesh_path_obj.split("/")[-1]+'.mtl')
|
95 |
|
96 |
+
end_time = time.time()
|
97 |
+
elapsed_time = end_time - start_time
|
98 |
+
print(f"uv takes {elapsed_time}s")
|
99 |
+
return mesh_path_glb+".obj"
|