meshonline / kinect-openni-bvh-saver

This project is based on OpenNI2, NITE2, and OpenCV2, it will automatically save many skeleton animation clips to bvh files.
MIT License
206 stars 57 forks source link

关于四元数的计算 #6

Open thunDL opened 5 years ago

thunDL commented 5 years ago

老师你好,我最近在做一个关于视频提取骨骼特征导入动画的项目,我现在已经获得了三维骨骼关节点的坐标,需要将它转换为BVH文件所表示的运动捕捉模型,在转换坐标到欧拉角的时候,我遇到了问题,所以阅读了您的代码。 但是其中有两点令我感到困惑,每个关节点旋转的变化应该是相对于其父节点,理论上只需要得到父节点指向它的向量和初始位姿的该向量计算便可以得出旋转矩阵再转换为欧拉角,但是为什么在您的代码中需要连接该关节点的所有骨骼信息?是否是因为像Hip这样的关节点连接多个关节点所以需要这样做? 还有在您的代码中,mat3应该是旋转矩阵,但是我不清除在mat3_from_axis中它是如何被转换的? 感谢老师指导。

meshonline commented 5 years ago

第一个问题,是这样的,有些关节连接多个关节点,所以保持所有的父子关系就可以方便查询了。 第二个问题,mat3是旋转矩阵,mat3_from_axis我是从网上找的代码,具体原理我也不是很清楚。

在 2019年7月25日,下午7:37,thunDL notifications@github.com 写道:

老师你好,我最近在做一个关于视频提取骨骼特征导入动画的项目,我现在已经获得了三维骨骼关节点的坐标,需要将它转换为BVH文件所表示的运动捕捉模型,在转换坐标到欧拉角的时候,我遇到了问题,所以阅读了您的代码。 但是其中有两点令我感到困惑,每个关节点旋转的变化应该是相对于其父节点,理论上只需要得到父节点指向它的向量和初始位姿的该向量计算便可以得出旋转矩阵再转换为欧拉角,但是为什么在您的代码中需要连接该关节点的所有骨骼信息?是否是因为像Hip这样的关节点连接多个关节点所以需要这样做? 还有在您的代码中,mat3应该是旋转矩阵,但是我不清除在mat3_from_axis中它是如何被转换的? 感谢老师指导。

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/meshonline/kinect-openni-bvh-saver/issues/6?email_source=notifications&email_token=ADJTTQ7TRGJA7ZF526SS6GTQBGF53A5CNFSM4IGZXB5KYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HBOTH3Q, or mute the thread https://github.com/notifications/unsubscribe-auth/ADJTTQ3OKM257QOTIKNHMXTQBGF53ANCNFSM4IGZXB5A.

thunDL commented 5 years ago

好的,谢谢老师,不过第一个问题我具体想问的是:

1.例如对于LEFT_HIP这一关节点,为什么需要对它的父节点和子节点都进行运算,计算某一关节点我认为只需要对其子节点,即v2这一向量与初始位姿计算其欧拉角应该就可以了吧,不知道我这想法错在哪里。 2.还有 // constrain to body's axis x不明白这一操作有何意义。 感谢老师的指导。

meshonline commented 5 years ago

计算两个节点的原因是获得绕轴旋转的方位,因为只计算一个节点,只能获得空间指向,它绕自己的轴旋转了多少度是任意的,只能再通过另一个条件来约束,那就是计算两根骨骼的夹角构成平面的法线,用它的方向作为绕轴旋转的约束,有了空间指向,再加上绕轴约束,就构成了完整的局部坐标系。 约束到身体的X轴,其实也可以不用的,之所以加上这个约束,是因为防止当腿往下伸的很直时,在180度的角度极小范围波动,计算出的vx会发生方向的剧烈跳变,导致身体剧烈前后翻转,所以用dot这个值,进行了组合计算,当角度接近180度时,使用身体的x轴,就是左胯与右胯的连线方向代替vx,保证了身体再腿伸直时也不会剧烈前后翻转。

在 2019年7月25日,下午8:52,thunDL notifications@github.com 写道:

好的,谢谢老师,不过第一个问题我具体想问的是:

// JOINT_LEFT_HIP p1 = joints[JOINT_LEFT_HIP].pos; p2 = joints[JOINT_LEFT_KNEE].pos; v1 = vec3_create(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z); p1 = joints[JOINT_LEFT_KNEE].pos; p2 = joints[JOINT_LEFT_FOOT].pos; v2 = vec3_create(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z); dot = vec3_dot(vec3_normalize(v1), vec3_normalize(v2)); vx = vec3_cross(vec3_normalize(v1), vec3_normalize(v2)); // constrain to body's axis x vx = vec3_add(vec3_mul_scalar(vec3_normalize(v_body_x), dot), vec3_mul_scalar(vec3_normalize(vx), 1 - dot)); // reverse the direction because knees can only bend to back vx = vec3_negate(vx); vy = v1; vz = vec3_zero; m = mat3_from_axis(vx, vy, vz); // inverse bind pose mr = mat3_inverse(mat3_rotation_z(kPi)); m = mat3_multiply(mr, m); q = quat_from_mat3(m); joints[JOINT_LEFT_HIP].quat = vec4_create(q.x, q.y, q.z, q.w); 1.例如对于LEFT_HIP这一关节点,为什么需要对它的父节点和子节点都进行运算,计算某一关节点我认为只需要对其子节点,即v2这一向量与初始位姿计算其欧拉角应该就可以了吧,不知道我这想法错在哪里。 2.还有 // constrain to body's axis x不明白这一操作有何意义。 感谢老师的指导。

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/meshonline/kinect-openni-bvh-saver/issues/6?email_source=notifications&email_token=ADJTTQ6R4DNKR6SGJULJPIDQBGOYNA5CNFSM4IGZXB5KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2ZL7II#issuecomment-515030945, or mute the thread https://github.com/notifications/unsubscribe-auth/ADJTTQ4ZQ2F34GJCJLJEMYTQBGOYNANCNFSM4IGZXB5A.

thunDL commented 5 years ago

好的,明白了,谢谢老师了

xorespesp commented 11 months ago

Hello, i have a question about quaternion calculation part. When calculating the quaternions for each joint, i found that the vx, vy, and vz vectors were commonly calculated. What exactly do these vectors mean?

For example, for a neck joint:

// JOINT_NECK
p1 = joints[JOINT_LEFT_SHOULDER].pos;
p2 = joints[JOINT_RIGHT_SHOULDER].pos;
vx = vec3_create(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z);
p1 = joints[JOINT_NECK].pos;
p2 = joints[JOINT_HEAD].pos;
vy = vec3_create(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z);
vz = vec3_zero;
m = mat3_from_axis(vx, vy, vz);
q = quat_from_mat3(m);
joints[JOINT_NECK].quat = vec4_create(q.x, q.y, q.z, q.w);

In code above, the difference in 3d position values between the left shoulder and right shoulder is set as the vx vector, the difference in 3d position values between the head and neck is set as the vy vector, and finally, vz is set as the zero vector.

I'm not sure what this behavior means exactly.

Any help would be appreciated. Thank you.

meshonline commented 11 months ago

Hello,

mat3_from_axis() is a function which I find from Internet, it needs three local axises to build a matrix, vx, xy, vz are three local axises of a joint, they can be calculated by the difference of the two limb positions.

I don’t know the details either, but the result is right:)

Regards,

Art

2023年11月16日 16:05,NoobUranium @.***> 写道:

Hello, i have a question about quaternion calculation part. When calculating the quaternions for each joint, i found that the vx, vy, and vz vectors were commonly calculated. What exactly do these vectors mean?

For example, for a neck joint:

// JOINT_NECK p1 = joints[JOINT_LEFT_SHOULDER].pos; p2 = joints[JOINT_RIGHT_SHOULDER].pos; vx = vec3_create(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z); p1 = joints[JOINT_NECK].pos; p2 = joints[JOINT_HEAD].pos; vy = vec3_create(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z); vz = vec3_zero; m = mat3_from_axis(vx, vy, vz); q = quat_from_mat3(m); joints[JOINT_NECK].quat = vec4_create(q.x, q.y, q.z, q.w); In code above, the difference in 3d position values between the left shoulder and right shoulder is set as the vx vector, the difference in 3d position values between the head and neck is set as the vy vector, and finally, vz is set as the zero vector.

I'm not sure what this behavior means exactly.

Any help would be appreciated. Thank you.

— Reply to this email directly, view it on GitHub https://github.com/meshonline/kinect-openni-bvh-saver/issues/6#issuecomment-1813961051, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADJTTQ3SMR4IY7MGK5PKR4DYEXCLVAVCNFSM4IGZXB5KU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBRGM4TMMJQGUYQ. You are receiving this because you commented.

xorespesp commented 11 months ago

Thank you for your reply!

And i have one more question. I'm currently working on converting the skeleton coordinates of the Azure Kinect Body Tracking SDK into BVH by referring to the quaternion calculation code of this project.

This generally works well, but there is one problem: the result skeleton's left and right sides are flipped.

To solve this problem, I first tried simply changing the R/L calculation, but I got a BVH with a completely wrong posture.

I'd like some advice on how to modify my quaternion calculations to solve this problem.

I don't have deep knowledge of quaternion.. so any help would be appreciated.

Thank you.

meshonline commented 11 months ago

My suggestion is to use absolute joint position to calculate everything, for example, Kinect SDK’ left hand joint position is the right hand joint position in another SDK, you can use the right hand joint position instead of the left hand position.

2023年11月17日 13:42,NoobUranium @.***> 写道:

Thank you for your reply!

And i have one more question. I'm currently working on converting the skeleton coordinates of the Azure Kinect Body Tracking SDK into BVH by referring to the quaternion calculation code of this project.

This generally works well, but there is one problem: the result skeleton's left and right sides are flipped.

To solve this problem, I first tried simply changing the R/L calculation, but I got a BVH with a completely wrong posture.

I'd like some advice on how to modify my quaternion calculations to solve this problem.

I don't have deep knowledge of quaternion.. so any help would be appreciated.

Thank you.

— Reply to this email directly, view it on GitHub https://github.com/meshonline/kinect-openni-bvh-saver/issues/6#issuecomment-1815779850, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADJTTQ3OIL6U7DTZEV5AGZDYE32L5AVCNFSM4IGZXB5KU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBRGU3TOOJYGUYA. You are receiving this because you commented.