mkocabas / PARE

Code for ICCV2021 paper PARE: Part Attention Regressor for 3D Human Body Estimation
Other
370 stars 73 forks source link

FBX output #7

Open alighofrani95 opened 2 years ago

alighofrani95 commented 2 years ago

I really thank you for sharing this state-of-the-art model. I just try to export the .fbx file (from vibe implementation) by it seems that there are some differences between vibe and pare in the SMPL pose parameters shape. the shape of pose in vibe is (n_frames, 72) but in pare is pose (n_frames, 24, 3, 3)

How can I export .fbx from the .pkl file generated via PARE?

Best regards,

CvHadesSun commented 2 years ago

@alighofrani95 , Hi, in this repo, output pose:(n_frames, 24, 3, 3) is rotation matrix format. Actually, in the VIBE repo output .fbx scripts, need to transform the Axis-angle format(n_frames, 24, 3) to rotation matrix format(n_frames, 24, 3, 3), so, you can directly use the rotation matrix format output to do you want, just not use https://github.com/mkocabas/VIBE/blob/03ed50d3121c37a4abfcc25dc995f08b63fd7f1f/lib/utils/fbx_output.py#L81. Another solution is, you can transform the rotation matrix format to Axis-angle format, which is the pose output format of VIBE:

def rotmat2rotvec(mat, unit_thresh=1e-5):
    """Return axis, angle and point from (3, 3) matrix `mat`
    Parameters
    ----------
    mat : array-like shape (3, 3)
        Rotation matrix
    unit_thresh : float, optional
        Tolerable difference from 1 when testing for unit eigenvalues to
        confirm `mat` is a rotation matrix.
    Returns
    -------
    axis : array shape (3,)
       vector giving axis of rotation
    angle : scalar
       angle of rotation in radians.
    Examples
    --------
    >>> direc = np.random.random(3) - 0.5
    >>> angle = (np.random.random() - 0.5) * (2*math.pi)
    >>> R0 = axangle2mat(direc, angle)
    >>> direc, angle = mat2axangle(R0)
    >>> R1 = axangle2mat(direc, angle)
    >>> np.allclose(R0, R1)
    True
    Notes
    -----
    http://en.wikipedia.org/wiki/Rotation_matrix#Axis_of_a_rotation
    Code from https://github.com/matthew-brett/transforms3d
    """
    M = np.asarray(mat, dtype=np.float)
    # direction: unit eigenvector of R33 corresponding to eigenvalue of 1
    L, W = np.linalg.eig(M.T)
    i = np.where(np.abs(L - 1.0) < unit_thresh)[0]
    if not len(i):
        raise ValueError("no unit eigenvector corresponding to eigenvalue 1")
    direction = np.real(W[:, i[-1]]).squeeze()
    # rotation angle depending on direction
    cosa = (np.trace(M) - 1.0) / 2.0
    if abs(direction[2]) > 1e-8:
        sina = (M[1, 0] + (cosa - 1.0) * direction[0] * direction[1]) / direction[2]
    elif abs(direction[1]) > 1e-8:
        sina = (M[0, 2] + (cosa - 1.0) * direction[0] * direction[2]) / direction[1]
    else:
        sina = (M[2, 1] + (cosa - 1.0) * direction[1] * direction[2]) / direction[0]
    angle = math.atan2(sina, cosa)
    # return direction, angle
    # print(np.linalg.norm(direction))  # 1
    # assert(np.linalg.norm(direction) == 1.0)
    return direction * angle

Hope that is useful to you!

godkath commented 1 year ago

@CvHadesSun Thank you for your reply.When I transform the rotation matrix format to fbx by use my own method,I find the results is upside down,how to overturn the Axis-angle format or rotation matrix format.

shngt commented 1 year ago

Could you please change the README.md so that it reflects this nuance? Currently it says the poses output will be in the shape (num_frames, 72), not (num_frames, 24, 3, 3)