Spaces:
Running
Running
import os | |
import cv2 | |
import numpy as np | |
import torch | |
import trimesh | |
import lib.vis.viewer as viewer_utils | |
from lib.vis.wham_tools.tools import checkerboard_geometry | |
def camera_marker_geometry(radius, height): | |
vertices = np.array( | |
[ | |
[-radius, -radius, 0], | |
[radius, -radius, 0], | |
[radius, radius, 0], | |
[-radius, radius, 0], | |
[0, 0, - height], | |
] | |
) | |
faces = np.array( | |
[[0, 1, 2], [0, 2, 3], [1, 0, 4], [2, 1, 4], [3, 2, 4], [0, 3, 4],] | |
) | |
face_colors = np.array( | |
[ | |
[0.5, 0.5, 0.5, 1.0], | |
[0.5, 0.5, 0.5, 1.0], | |
[0.0, 1.0, 0.0, 1.0], | |
[1.0, 0.0, 0.0, 1.0], | |
[0.0, 1.0, 0.0, 1.0], | |
[1.0, 0.0, 0.0, 1.0], | |
] | |
) | |
return vertices, faces, face_colors | |
def run_vis2_on_video(res_dict, res_dict2, output_pth, focal_length, image_names, R_c2w=None, t_c2w=None): | |
img0 = cv2.imread(image_names[0]) | |
height, width, _ = img0.shape | |
world_mano = {} | |
world_mano['vertices'] = res_dict['vertices'] | |
world_mano['faces'] = res_dict['faces'] | |
world_mano2 = {} | |
world_mano2['vertices'] = res_dict2['vertices'] | |
world_mano2['faces'] = res_dict2['faces'] | |
vis_dict = {} | |
color_idx = 0 | |
world_mano['vertices'] = world_mano['vertices'] | |
for _id, _verts in enumerate(world_mano['vertices']): | |
verts = _verts.cpu().numpy() # T, N, 3 | |
body_faces = world_mano['faces'] | |
body_meshes = { | |
"v3d": verts, | |
"f3d": body_faces, | |
"vc": None, | |
"name": f"hand_{_id}", | |
# "color": "pace-green", | |
"color": "director-purple", | |
} | |
vis_dict[f"hand_{_id}"] = body_meshes | |
color_idx += 1 | |
world_mano2['vertices'] = world_mano2['vertices'] | |
for _id, _verts in enumerate(world_mano2['vertices']): | |
verts = _verts.cpu().numpy() # T, N, 3 | |
body_faces = world_mano2['faces'] | |
body_meshes = { | |
"v3d": verts, | |
"f3d": body_faces, | |
"vc": None, | |
"name": f"hand2_{_id}", | |
# "color": "pace-blue", | |
"color": "director-blue", | |
} | |
vis_dict[f"hand2_{_id}"] = body_meshes | |
color_idx += 1 | |
v, f, vc, fc = checkerboard_geometry(length=100, c1=0, c2=0, up="z") | |
v[:, 2] -= 2 # z plane | |
gound_meshes = { | |
"v3d": v, | |
"f3d": f, | |
"vc": vc, | |
"name": "ground", | |
"fc": fc, | |
"color": -1, | |
} | |
vis_dict["ground"] = gound_meshes | |
num_frames = len(world_mano['vertices'][_id]) | |
Rt = np.zeros((num_frames, 3, 4)) | |
Rt[:, :3, :3] = R_c2w[:num_frames] | |
Rt[:, :3, 3] = t_c2w[:num_frames] | |
verts, faces, face_colors = camera_marker_geometry(0.05, 0.1) | |
verts = np.einsum("tij,nj->tni", Rt[:, :3, :3], verts) + Rt[:, None, :3, 3] | |
camera_meshes = { | |
"v3d": verts, | |
"f3d": faces, | |
"vc": None, | |
"name": "camera", | |
"fc": face_colors, | |
"color": -1, | |
} | |
vis_dict["camera"] = camera_meshes | |
side_source = torch.tensor([0.463, -0.478, 2.456]) | |
side_target = torch.tensor([0.026, -0.481, -3.184]) | |
up = torch.tensor([1.0, 0.0, 0.0]) | |
view_camera = lookat_matrix(side_source, side_target, up) | |
viewer_Rt = np.tile(view_camera[:3, :4], (num_frames, 1, 1)) | |
meshes = viewer_utils.construct_viewer_meshes( | |
vis_dict, draw_edges=False, flat_shading=False | |
) | |
vis_h, vis_w = (1000, 1000) | |
K = np.array( | |
[ | |
[1000, 0, vis_w / 2], | |
[0, 1000, vis_h / 2], | |
[0, 0, 1] | |
] | |
) | |
data = viewer_utils.ViewerData(viewer_Rt, K, vis_w, vis_h) | |
batch = (meshes, data) | |
viewer = viewer_utils.ARCTICViewer(interactive=True, size=(vis_w, vis_h)) | |
viewer.render_seq(batch, out_folder=os.path.join(output_pth, 'aitviewer')) | |
def run_vis2_on_video_cam(res_dict, res_dict2, output_pth, focal_length, image_names, R_w2c=None, t_w2c=None): | |
img0 = cv2.imread(image_names[0]) | |
height, width, _ = img0.shape | |
world_mano = {} | |
world_mano['vertices'] = res_dict['vertices'] | |
world_mano['faces'] = res_dict['faces'] | |
world_mano2 = {} | |
world_mano2['vertices'] = res_dict2['vertices'] | |
world_mano2['faces'] = res_dict2['faces'] | |
vis_dict = {} | |
color_idx = 0 | |
world_mano['vertices'] = world_mano['vertices'] | |
for _id, _verts in enumerate(world_mano['vertices']): | |
verts = _verts.cpu().numpy() # T, N, 3 | |
body_faces = world_mano['faces'] | |
body_meshes = { | |
"v3d": verts, | |
"f3d": body_faces, | |
"vc": None, | |
"name": f"hand_{_id}", | |
# "color": "pace-green", | |
"color": "director-purple", | |
} | |
vis_dict[f"hand_{_id}"] = body_meshes | |
color_idx += 1 | |
world_mano2['vertices'] = world_mano2['vertices'] | |
for _id, _verts in enumerate(world_mano2['vertices']): | |
verts = _verts.cpu().numpy() # T, N, 3 | |
body_faces = world_mano2['faces'] | |
body_meshes = { | |
"v3d": verts, | |
"f3d": body_faces, | |
"vc": None, | |
"name": f"hand2_{_id}", | |
# "color": "pace-blue", | |
"color": "director-blue", | |
} | |
vis_dict[f"hand2_{_id}"] = body_meshes | |
color_idx += 1 | |
meshes = viewer_utils.construct_viewer_meshes( | |
vis_dict, draw_edges=False, flat_shading=False | |
) | |
num_frames = len(world_mano['vertices'][_id]) | |
Rt = np.zeros((num_frames, 3, 4)) | |
Rt[:, :3, :3] = R_w2c[:num_frames] | |
Rt[:, :3, 3] = t_w2c[:num_frames] | |
cols, rows = (width, height) | |
K = np.array( | |
[ | |
[focal_length, 0, width / 2], | |
[0, focal_length, height / 2], | |
[0, 0, 1] | |
] | |
) | |
vis_h = height | |
vis_w = width | |
data = viewer_utils.ViewerData(Rt, K, cols, rows, imgnames=image_names) | |
batch = (meshes, data) | |
viewer = viewer_utils.ARCTICViewer(interactive=True, size=(vis_w, vis_h)) | |
viewer.render_seq(batch, out_folder=os.path.join(output_pth, 'aitviewer')) | |
def lookat_matrix(source_pos, target_pos, up): | |
""" | |
IMPORTANT: USES RIGHT UP BACK XYZ CONVENTION | |
:param source_pos (*, 3) | |
:param target_pos (*, 3) | |
:param up (3,) | |
""" | |
*dims, _ = source_pos.shape | |
up = up.reshape(*(1,) * len(dims), 3) | |
up = up / torch.linalg.norm(up, dim=-1, keepdim=True) | |
back = normalize(target_pos - source_pos) | |
right = normalize(torch.linalg.cross(up, back)) | |
up = normalize(torch.linalg.cross(back, right)) | |
R = torch.stack([right, up, back], dim=-1) | |
return make_4x4_pose(R, source_pos) | |
def make_4x4_pose(R, t): | |
""" | |
:param R (*, 3, 3) | |
:param t (*, 3) | |
return (*, 4, 4) | |
""" | |
dims = R.shape[:-2] | |
pose_3x4 = torch.cat([R, t.view(*dims, 3, 1)], dim=-1) | |
bottom = ( | |
torch.tensor([0, 0, 0, 1], device=R.device) | |
.reshape(*(1,) * len(dims), 1, 4) | |
.expand(*dims, 1, 4) | |
) | |
return torch.cat([pose_3x4, bottom], dim=-2) | |
def normalize(x): | |
return x / torch.linalg.norm(x, dim=-1, keepdim=True) | |
def save_mesh_to_obj(vertices, faces, file_path): | |
# 创建一个 Trimesh 对象 | |
mesh = trimesh.Trimesh(vertices=vertices, faces=faces) | |
# 导出为 .obj 文件 | |
mesh.export(file_path) | |
print(f"Mesh saved to {file_path}") | |