Files
hand-motion-pipeline/third_party/Dyn-HaMR/dyn-hamr/optim/output.py
T

189 lines
6.0 KiB
Python

import os
import imageio
import glob
import json
import subprocess
import numpy as np
import torch
from util.tensor import move_to, detach_all, to_torch
from util.logger import Logger
def get_results_paths(res_dir):
"""
get the iterations of all saved results in res_dir
:param res_dir (str) result dir
returns a dict of iter to result path
"""
res_files = sorted(glob.glob(f"{res_dir}/*_results.npz"))
print(f"found {len(res_files)} results in {res_dir}")
path_dict = {}
for res_file in res_files:
it, name, _ = os.path.basename(res_file).split("_")[-3:]
assert name in ["world", "prior"]
if it not in path_dict:
path_dict[it] = {}
path_dict[it][name] = res_file
return path_dict
def load_result(res_path_dict):
"""
load all saved results for a given iteration
:param res_path_dict (dict) paths to relevant results
returns dict of results
"""
res_dict = {}
for name, path in res_path_dict.items():
res = np.load(path)
res_dict[name] = to_torch({k: res[k] for k in res.files})
return res_dict
def save_initial_predictions(model, out_dir, seq_name):
os.makedirs(out_dir, exist_ok=True)
with torch.no_grad():
print('go into get_optim_result from output.py save_initial_predictions')
pred_dict = model.get_optim_result()
pred_dict = move_to(detach_all(pred_dict), "cpu")
for name, results in pred_dict.items():
out_path = f"{out_dir}/{seq_name}_{0:06d}_init_{name}_results.npz"
Logger.log(f"saving initial results to {out_path}")
np.savez(out_path, **results)
# print('cam_R in save_initial_predictions: ', results['cam_R'].shape, results['cam_R'])
# print((results['cam_R'][0] == results['cam_R'][1]).all())
# print((results['cam_R'][1] == results['cam_R'][2]).all())
# print((results['cam_R'][2] == results['cam_R'][3]).all())
# print((results['cam_R'][3] == results['cam_R'][4]).all())
# print((results['cam_R'][4] == results['cam_R'][5]).all())
# print((results['cam_R'][5] == results['cam_R'][6]).all())
def save_input_poses(dataset, out_dir, seq_name, name="phalp"):
os.makedirs(out_dir, exist_ok=True)
dataset.load_data(interp_input=False)
d = dataset.data_dict
res = {
"pose_body": np.stack(d["init_body_pose"], axis=0),
"trans": np.stack(d["init_trans"], axis=0),
"root_orient": np.stack(d["init_root_orient"], axis=0),
}
print({k: v.shape for k, v in res.items()})
out_path = f"{out_dir}/{seq_name}_{0:06d}_{name}_world_results.npz"
Logger.log(f"saving inputs to {out_path}")
np.savez(out_path, **res)
def save_input_frames_ffmpeg(dataset, out_dir, name="input", fps=30, overwrite=False):
vid_path = f"{out_dir}/{name}.mp4"
if not overwrite and os.path.isfile(vid_path):
return
list_path = f"{out_dir}/src_paths.txt"
with open(list_path, "w") as f:
f.write("\n".join([f"file '{p}'" for p in dataset.sel_img_paths]))
filter_str = f"-framerate {fps} -vf 'format=yuv420p'"
cmd = (
f"ffmpeg -loglevel error -f concat -safe 0 "
f"-i {list_path} -c:v libx264 {filter_str} {vid_path} -y"
)
print(cmd)
subprocess.call(cmd, shell=True, stdin=subprocess.PIPE)
print(f"SAVED {len(dataset.sel_img_paths)} INPUT FRAMES TO {vid_path}")
return vid_path
def save_input_frames(dataset, vid_path, fps=30, overwrite=False):
if not overwrite and os.path.isfile(vid_path):
return
writer = imageio.get_writer(vid_path, fps=fps)
for path in dataset.sel_img_paths:
writer.append_data(imageio.imread(path))
writer.close()
print(f"SAVED {len(dataset.sel_img_paths)} INPUT FRAMES TO {vid_path}")
return vid_path
def load_track_info(path):
assert os.path.isfile(path)
with open(path, "r") as f:
track_info = json.load(f)
meta = track_info["meta"]
tracks = track_info["tracks"]
track_ids, idcs, vis_masks = map(
torch.as_tensor,
zip(
*[
(int(tid), info["index"], info["vis_mask"])
for tid, info in tracks.items()
]
),
)
track_ids = track_ids[idcs]
vis_masks = vis_masks[idcs]
data_interval = meta["data_interval"]
seq_interval = meta["seq_interval"]
return track_ids, vis_masks, data_interval, seq_interval
def save_track_info(dataset, out_dir):
# track indices are relative to the entire sequence
track_ids = dataset.track_ids
track_dict = {}
for i, (tid, mask) in enumerate(zip(dataset.track_ids, dataset.track_vis_masks)):
track_dict[int(tid)] = {"index": i, "vis_mask": mask.tolist()}
out_dict = {
"tracks": track_dict,
"meta": {
"seq_interval": (int(dataset.start_idx), int(dataset.end_idx)),
"data_interval": (int(dataset.data_start), int(dataset.data_end)),
},
}
with open(f"{out_dir}/track_info.json", "w") as f:
json.dump(out_dict, f)
print("SAVED TRACK INFO")
def load_camera_json(path):
assert os.path.isfile(path)
with open(path, "r") as f:
cam_data = json.load(f)
R = torch.as_tensor(cam_data["rotation"]).reshape(-1, 3, 3)
t = torch.as_tensor(cam_data["translation"])
intrins = torch.as_tensor(cam_data["intrinsics"])
return R.float(), t.float(), intrins.float()
def save_camera_json(path, cam_R, cam_t, intrins):
"""
:param path
:param cam_R (N, 3, 3)
:param cam_t (N, 3)
:param intrins (N, 4)
"""
N = len(cam_R)
T = torch.tensor([[1, 0, 0], [0, -1, 0], [0, 0, -1]], dtype=torch.float32)
cam_R = torch.einsum("ij,bjk->bik", T, cam_R)
cam_t = torch.einsum("ij,bj->bi", T, cam_t)
with open(path, "w") as f:
json.dump(
{
"rotation": cam_R.reshape(N, 9).tolist(),
"translation": cam_t.tolist(),
"intrinsics": intrins.tolist(),
},
f,
indent=1,
)