Jeff-sjtu / HybrIK

Official code of "HybrIK: A Hybrid Analytical-Neural Inverse Kinematics Solution for 3D Human Pose and Shape Estimation", CVPR 2021
MIT License
1.21k stars 147 forks source link

For anyone would like visualize pkl animation without blender, here is a straight-forward way! #161

Open luohao123 opened 1 year ago

luohao123 commented 1 year ago

By using pip install nosmpl

I found this script can visualize HybrIK pkl file directly:

37_1680705278

import numpy as np
from nosmpl.vis.vis_o3d import vis_mesh_o3d, Open3DVisualizer
from nosmpl.utils import rot_mat_to_euler, rotmat_to_rotvec, quat2mat, quat_to_rotvec
import sys
import pickle
from nosmpl.smpl_onnx import SMPLOnnxRuntime

def vis_pkl():    
    smpl = SMPLOnnxRuntime()

    data_f = sys.argv[1]
    data = pickle.load(open(data_f, "rb"))
    ks = list(data.keys())
    print(ks)

    o3d_vis = Open3DVisualizer(fps=60, save_img_folder="results/", enable_axis=False)

    frame_len = len(data[ks[0]])
    print("frames: ", frame_len)
    for fi in range(frame_len):
        pose = data['pred_thetas'][fi]
        pose = np.array(pose).reshape(-1, 3, 3)
        print(pose.shape)

        trans = data["transl"][fi]

        pose_rotvec = [rotmat_to_rotvec(p) for p in pose]
        pose_rotvec = np.array(pose_rotvec).reshape(-1, 3)
        print(pose_rotvec.shape)

        # global_orient = pose_rotvec[:, :3].astype(np.float32)
        global_orient = np.array([[0, 0, 0]], dtype=np.float32).reshape([1, 1, 3])
        # global_orient = [[i[0], -i[1], i[2]] for i in global_orient]
        # global_orient = np.array(global_orient).astype(np.float32)

        pose_rotvec_body = np.delete(pose_rotvec, [-1], axis=0).reshape(1, 23, 3)
        body = pose_rotvec_body.astype(np.float32)
        # lhand = np.zeros([1, 45]).astype(np.float32)
        # rhand = np.zeros([1, 45]).astype(np.float32)

        outputs = smpl.forward(body, global_orient)

        vertices, joints, faces = outputs
        vertices = vertices[0].squeeze()
        joints = joints[0].squeeze()

        faces = faces.astype(np.int32)
        # vis_mesh_o3d(vertices, faces)
        # vertices += trans
        # trans = [trans[1], trans[0], trans[2]]
        trans = [trans[0], trans[1], 0]
        print(trans)
        o3d_vis.update(vertices, faces, trans, R_along_axis=[np.pi, 0, 0], waitKey=1)
    o3d_vis.release()

if __name__ == "__main__":
    vis_pkl()

Hope it helps!

chris-hndz commented 9 months ago

How should this code be modified to display the SMPL-X pkl animation?

Thank you in advance! 😄

Brian417-cup commented 6 months ago

By using pip install nosmpl

I found this script can visualize HybrIK pkl file directly:

37_1680705278 37_1680705278

import numpy as np
from nosmpl.vis.vis_o3d import vis_mesh_o3d, Open3DVisualizer
from nosmpl.utils import rot_mat_to_euler, rotmat_to_rotvec, quat2mat, quat_to_rotvec
import sys
import pickle
from nosmpl.smpl_onnx import SMPLOnnxRuntime

def vis_pkl():    
    smpl = SMPLOnnxRuntime()

    data_f = sys.argv[1]
    data = pickle.load(open(data_f, "rb"))
    ks = list(data.keys())
    print(ks)

    o3d_vis = Open3DVisualizer(fps=60, save_img_folder="results/", enable_axis=False)

    frame_len = len(data[ks[0]])
    print("frames: ", frame_len)
    for fi in range(frame_len):
        pose = data['pred_thetas'][fi]
        pose = np.array(pose).reshape(-1, 3, 3)
        print(pose.shape)

        trans = data["transl"][fi]

        pose_rotvec = [rotmat_to_rotvec(p) for p in pose]
        pose_rotvec = np.array(pose_rotvec).reshape(-1, 3)
        print(pose_rotvec.shape)

        # global_orient = pose_rotvec[:, :3].astype(np.float32)
        global_orient = np.array([[0, 0, 0]], dtype=np.float32).reshape([1, 1, 3])
        # global_orient = [[i[0], -i[1], i[2]] for i in global_orient]
        # global_orient = np.array(global_orient).astype(np.float32)

        pose_rotvec_body = np.delete(pose_rotvec, [-1], axis=0).reshape(1, 23, 3)
        body = pose_rotvec_body.astype(np.float32)
        # lhand = np.zeros([1, 45]).astype(np.float32)
        # rhand = np.zeros([1, 45]).astype(np.float32)

        outputs = smpl.forward(body, global_orient)

        vertices, joints, faces = outputs
        vertices = vertices[0].squeeze()
        joints = joints[0].squeeze()

        faces = faces.astype(np.int32)
        # vis_mesh_o3d(vertices, faces)
        # vertices += trans
        # trans = [trans[1], trans[0], trans[2]]
        trans = [trans[0], trans[1], 0]
        print(trans)
        o3d_vis.update(vertices, faces, trans, R_along_axis=[np.pi, 0, 0], waitKey=1)
    o3d_vis.release()

if __name__ == "__main__":
    vis_pkl()

Hope it helps!

Hey, I discovered you directly use root translation in camera space with (x,y,0). Actually, the author has provided a relative code transfer point from camera space into pixel space with corresponding focal length, maybe using the transfer will have a better visualization!!

jiajiajibamaoss commented 5 months ago

(hybrik3d) mocap3d@mocap3D:~/HybrIK$ python scripts/jjj.py Traceback (most recent call last): File "/home/mocap3d/HybrIK/scripts/jjj.py", line 59, in vis_pkl() File "/home/mocap3d/HybrIK/scripts/jjj.py", line 10, in vis_pkl smpl = SMPLOnnxRuntime() File "/home/mocap3d/anaconda3/envs/hybrik3d/lib/python3.9/site-packages/nosmpl/smpl_onnx.py", line 24, in init download('https://github.com/jinfagang/nosmpl/releases/download/v1.1/smpl.onnx', NameError: name 'download' is not defined