Closed hanhailangya closed 4 years ago
1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?
主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例 https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L204-L209 在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
2.不同关节点定义的旋转顺序的原理是什么?
其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样. https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L171 zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.
谢谢您的解答~
在 2020-06-26 16:44:55,KevinLTT notifications@github.com 写道:
1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?
主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例 https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L204-L209 在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
2.不同关节点定义的旋转顺序的原理是什么?
其实在最后输出bvh的时候关节点的旋转顺序都是zyx, 只是在求旋转角度的时候向量选取的顺序不一样. https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L171 zyx的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.
您好,请问如果是手势的话,那么应该如何建立手的模板以及计算每个关节点的向量
您好,请问如果是手势的话,那么应该如何建立手的模板以及计算每个关节点的向量
可以看这个issues #26 我觉得主要是3步, 1) 根据掌指关节求掌平面 2) 根据求掌指关节和掌片面之间的夹角 3) 求其他关节的夹角 1)是四点求平面 2)是求向量和平面夹角 3)是求向量之间的夹角 注意掌指关节有两个自由度, 其他关节只有一个
@hanhailangya @KevinLTT 前辈们,针对这句话:
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
此处的x_dir 和 y_dir 不是同一个方向的吗?
若能解惑,不胜感激
@hanhailangya @KevinLTT 前辈们,针对这句话:
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
- 竟然已经求出xz平面,并且进行叉乘求出y轴方向,那不是已经了确定新的xyz轴向了,为何还要再z轴和y轴做叉乘求出x轴方向,这个新的x和原先设定的Hips->RightUpLeg向量x不是一样的吗
- 我也对 About direction vector #14 (comment) 存在疑惑,在初始restpose中:
此处的x_dir 和 y_dir 不是同一个方向的吗?
若能解惑,不胜感激
朋友,你好 请问你这个图是怎么可视化出来的呀?是在blender打开还是用了什么插件
@weidom 是的,blender打开的
@hanhailangya @KevinLTT 前辈们,针对这句话:
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
- 竟然已经求出xz平面,并且进行叉乘求出y轴方向,那不是已经了确定新的xyz轴向了,为何还要再z轴和y轴做叉乘求出x轴方向,这个新的x和原先设定的Hips->RightUpLeg向量x不是一样的吗
- 我也对 About direction vector #14 (comment) 存在疑惑,在初始restpose中:
此处的x_dir 和 y_dir 不是同一个方向的吗?
若能解惑,不胜感激
1.每次输入都有一个为None,另两个不为None,但是另两个本身并不是正交的,这个代码做的其实是通过输入的第一个axis和由第一第三个axis确定的平面来生成一个新的坐标系。所以上面最后要再对z和y做叉乘得到新的x,这样的x才是正交的。 2.至于这个问题,同一个方向只是因为在tpose里是这样,后续每一帧这俩大部分时候都不是同一个方向。不过如果真的是同一个方向我也没想清楚会不会有问题。
@ZaVang 转眼过了半年,已经弄懂,当年要是有您提点我会懂的更快 ,总之多谢回复
@ZaVang 转眼过了半年,已经弄懂,当年要是有您提点我会懂的更快 ,总之多谢回复 没有没有,我也是刚刚入门的初学者,还有很多地方不懂。请问您现在知道这个eulermap里面每一个关节的x_dir,y_dir,z_dir的具体选择原理吗;比如下面这个 if joint == 'Hip': x_dir = pose[index['LeftHip']] - pose[index['RightHip']] y_dir = None z_dir = pose[index['Spine']] - pose[joint_idx] order = 'zyx' 为什么x_dir是lefthip-righthip而不能是lefthip-hip或者hip-righthip? 再比如这里 elif joint == 'Thorax': x_dir = pose[index['LeftShoulder']] - \ pose[index['RightShoulder']] y_dir = None z_dir = pose[joint_idx] - pose[index['Spine']] order = 'zyx' 为什么z_dir不能是neck-thorax? 谢谢!
@ZaVang 因为每一帧的旋转是相对初始T-pose计算,所以在每一帧3D点上建立坐标系的朝向应当与T-pose保持一致,这样比较两个frame的旋转计算出的旋转矩阵才是正确的,你可以看看捕获点,其实lefthip-righthip与lefthip-hip的向量方向并不一致
@wtnan2003
感谢回复!我对您的回答还是有些疑问,在源代码中给出的initial direction来看,lefthip,hip和righthip都在平行于x轴的一条直线上,所以为了和T-pose保持一致,其实lefthip-righthip与lefthip-hip的向量方向都可以吧?当然后续每一帧的数据中这俩方向肯定是不一样的。假设一种情况,对于某一帧的坐标,我们去掉右半边的所有节点,那么毫无疑问应该选择lefthip-hip的方向吧,这时候再单独加上一个righthip的节点,让他和这一帧中righthip的坐标一致,这时候按理说只需要重新计算这一个节点的旋转矩阵即可吧。 所以我的意思是这样的选择方式应该不是唯一的?根据我的理解来看选择沿着坐标轴方向可能计算上确实方便很多。具体的您可以看看我最新提的issue
@hanhailangya @KevinLTT 前辈们,针对这句话:
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
- 竟然已经求出xz平面,并且进行叉乘求出y轴方向,那不是已经了确定新的xyz轴向了,为何还要再z轴和y轴做叉乘求出x轴方向,这个新的x和原先设定的Hips->RightUpLeg向量x不是一样的吗
- 我也对 About direction vector #14 (comment) 存在疑惑,在初始restpose中:
此处的x_dir 和 y_dir 不是同一个方向的吗? 若能解惑,不胜感激
1.每次输入都有一个为None,另两个不为None,但是另两个本身并不是正交的,这个代码做的其实是通过输入的第一个axis和由第一第三个axis确定的平面来生成一个新的坐标系。所以上面最后要再对z和y做叉乘得到新的x,这样的x才是正交的。 2.至于这个问题,同一个方向只是因为在tpose里是这样,后续每一帧这俩大部分时候都不是同一个方向。不过如果真的是同一个方向我也没想清楚会不会有问题。
@ZaVang 您好老兄,针对您的回复1.,我想向您请教一个问题。还是以右大腿RightUpLeg为例,即在不改变其他function函数的情况下,是否一定是‘zyx’的顺序呢,或者可以这么说:如果我用xz平面先叉乘得到新的y,再利用x和y做叉乘得到新的z,此时z是正交的,那么顺序是否可以换成‘xyz’而不用‘zyx’呢?假设换成xyz的话,后续代码会有何种影响呢?或者说在blender中的效果是否有区别呢?因为y确实是未知的,放在中间用xz的叉积求解可以理解,但是x、z的顺序会有影响吗?
@hanhailangya @KevinLTT 前辈们,针对这句话:
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
- 竟然已经求出xz平面,并且进行叉乘求出y轴方向,那不是已经了确定新的xyz轴向了,为何还要再z轴和y轴做叉乘求出x轴方向,这个新的x和原先设定的Hips->RightUpLeg向量x不是一样的吗
- 我也对 About direction vector #14 (comment) 存在疑惑,在初始restpose中:
此处的x_dir 和 y_dir 不是同一个方向的吗? 若能解惑,不胜感激
1.每次输入都有一个为None,另两个不为None,但是另两个本身并不是正交的,这个代码做的其实是通过输入的第一个axis和由第一第三个axis确定的平面来生成一个新的坐标系。所以上面最后要再对z和y做叉乘得到新的x,这样的x才是正交的。 2.至于这个问题,同一个方向只是因为在tpose里是这样,后续每一帧这俩大部分时候都不是同一个方向。不过如果真的是同一个方向我也没想清楚会不会有问题。
@ZaVang 您好老兄,针对您的回复1.,我想向您请教一个问题。还是以右大腿RightUpLeg为例,即在不改变其他function函数的情况下,是否一定是‘zyx’的顺序呢,或者可以这么说:如果我用xz平面先叉乘得到新的y,再利用x和y做叉乘得到新的z,此时z是正交的,那么顺序是否可以换成‘xyz’而不用‘zyx’呢?假设换成xyz的话,后续代码会有何种影响呢?或者说在blender中的效果是否有区别呢?因为y确实是未知的,放在中间用xz的叉积求解可以理解,但是x、z的顺序会有影响吗?
xyz和zyx的差别就是看哪一个轴是基准,这里的基准意思就是你选了哪个方向作为其中一个坐标轴。你可以试试看只改变顺序得到的结果。我其实也没有完全理解每一个joint他这些x、y、z轴是怎么选的,就你举例的点来说,按我的理解应该是xyz,因为初始的direction是[-1,0,0],但是作者给出的代码实际上确实是没问题。这一块我也不知道怎么解释了。你可以先试试就改变这一个点的xyz顺序,结果如何变化。
@hanhailangya @KevinLTT 前辈们,针对这句话:
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
- 竟然已经求出xz平面,并且进行叉乘求出y轴方向,那不是已经了确定新的xyz轴向了,为何还要再z轴和y轴做叉乘求出x轴方向,这个新的x和原先设定的Hips->RightUpLeg向量x不是一样的吗
- 我也对 About direction vector #14 (comment) 存在疑惑,在初始restpose中:
此处的x_dir 和 y_dir 不是同一个方向的吗? 若能解惑,不胜感激
1.每次输入都有一个为None,另两个不为None,但是另两个本身并不是正交的,这个代码做的其实是通过输入的第一个axis和由第一第三个axis确定的平面来生成一个新的坐标系。所以上面最后要再对z和y做叉乘得到新的x,这样的x才是正交的。 2.至于这个问题,同一个方向只是因为在tpose里是这样,后续每一帧这俩大部分时候都不是同一个方向。不过如果真的是同一个方向我也没想清楚会不会有问题。
@ZaVang 您好老兄,针对您的回复1.,我想向您请教一个问题。还是以右大腿RightUpLeg为例,即在不改变其他function函数的情况下,是否一定是‘zyx’的顺序呢,或者可以这么说:如果我用xz平面先叉乘得到新的y,再利用x和y做叉乘得到新的z,此时z是正交的,那么顺序是否可以换成‘xyz’而不用‘zyx’呢?假设换成xyz的话,后续代码会有何种影响呢?或者说在blender中的效果是否有区别呢?因为y确实是未知的,放在中间用xz的叉积求解可以理解,但是x、z的顺序会有影响吗?
xyz和zyx的差别就是看哪一个轴是基准,这里的基准意思就是你选了哪个方向作为其中一个坐标轴。你可以试试看只改变顺序得到的结果。我其实也没有完全理解每一个joint他这些x、y、z轴是怎么选的,就你举例的点来说,按我的理解应该是xyz,因为初始的direction是[-1,0,0],但是作者给出的代码实际上确实是没问题。这一块我也不知道怎么解释了。你可以先试试就改变这一个点的xyz顺序,结果如何变化。
好的老兄,我再尝试一下,感谢!
@hujb48 我今天看机器人学的时候发现了我之前一直理解错了。上面的例子rightupleg确实应该是zyx的顺序。在计算rightupleg的子节点rightknee的坐标的时候,需要的是rightupleg处的旋转矩阵,由于rightknee的初始向量是(0,0,-1),因此rightupleg处的旋转矩阵的第三行应该要平行于rightupleg-rightknee。所以应该以此为基准选择zyx的顺序。 而我之前不能理解的Hip处的旋转矩阵其实是近似的旋转。因为实际上lefthip、righthip和spine的位置应该只取决于offset和hip处的旋转矩阵,因此这三个点和hip,他们四个的相对位置应该是固定的,我看了blender里的结果发现好像确实是这样。因此按照上面的逻辑z轴要和spine-hip平行,x的正向轴要和lefthip-hip平行,x的负向轴和hip-righthip平行,这样有三个方程,但是因为这几个点相对位置是固定的,必然不能全部满足,所以作者的代码里选择了z轴与spine-hip平行,然后把另两个方程合在了一起,满足了righthip-lefthip和x轴平行。 我也是刚入门,自己摸索出来的上面结论,可能也还有不正确不到位的地方,兄弟你可以自己也实验看下我说的对不对。
@hujb48 我今天看机器人学的时候发现了我之前一直理解错了。上面的例子rightupleg确实应该是zyx的顺序。在计算rightupleg的子节点rightknee的坐标的时候,需要的是rightupleg处的旋转矩阵,由于rightknee的初始向量是(0,0,-1),因此rightupleg处的旋转矩阵的第三行应该要平行于rightupleg-rightknee。所以应该以此为基准选择zyx的顺序。 而我之前不能理解的Hip处的旋转矩阵其实是近似的旋转。因为实际上lefthip、righthip和spine的位置应该只取决于offset和hip处的旋转矩阵,因此这三个点和hip,他们四个的相对位置应该是固定的,我看了blender里的结果发现好像确实是这样。因此按照上面的逻辑z轴要和spine-hip平行,x的正向轴要和lefthip-hip平行,x的负向轴和hip-righthip平行,这样有三个方程,但是因为这几个点相对位置是固定的,必然不能全部满足,所以作者的代码里选择了z轴与spine-hip平行,然后把另两个方程合在了一起,满足了righthip-lefthip和x轴平行。 我也是刚入门,自己摸索出来的上面结论,可能也还有不正确不到位的地方,兄弟你可以自己也实验看下我说的对不对。
@ZaVang 感谢老哥您的回复以及非常详细讲解,受益匪浅,但我仍弄不懂的两个个问题:
@hujb48 我今天看机器人学的时候发现了我之前一直理解错了。上面的例子rightupleg确实应该是zyx的顺序。在计算rightupleg的子节点rightknee的坐标的时候,需要的是rightupleg处的旋转矩阵,由于rightknee的初始向量是(0,0,-1),因此rightupleg处的旋转矩阵的第三行应该要平行于rightupleg-rightknee。所以应该以此为基准选择zyx的顺序。 而我之前不能理解的Hip处的旋转矩阵其实是近似的旋转。因为实际上lefthip、righthip和spine的位置应该只取决于offset和hip处的旋转矩阵,因此这三个点和hip,他们四个的相对位置应该是固定的,我看了blender里的结果发现好像确实是这样。因此按照上面的逻辑z轴要和spine-hip平行,x的正向轴要和lefthip-hip平行,x的负向轴和hip-righthip平行,这样有三个方程,但是因为这几个点相对位置是固定的,必然不能全部满足,所以作者的代码里选择了z轴与spine-hip平行,然后把另两个方程合在了一起,满足了righthip-lefthip和x轴平行。 我也是刚入门,自己摸索出来的上面结论,可能也还有不正确不到位的地方,兄弟你可以自己也实验看下我说的对不对。
@ZaVang 感谢老哥您的回复以及非常详细讲解,受益匪浅,但我仍弄不懂的两个个问题:
- 就是针对每个joint,其旋转顺序的第一个轴dir的设置都是父节点-子节点的相应设置,这个好理解,那么旋转顺序的第三个轴是如何进行设置的?例如cmu中的“joint==‘LeftForeArm’这个点,顺序是xzy,那么x_dir就是‘LeftHand’->'LeftForeArm', 但是为何y_dir设置成'LeftForeArm'->'LeftArm',而不选择z_dir设置成'LeftForeArm'->'LeftArm',y_dir=None,此时顺序为xyz呢?这个设置应该如何判断?还是说按我说的设置其实本质上没有区别,只是轴的叫法不一样?
- 另外第三个轴到底应该如何进行选择哪些点间向量设置较为合适?因为我看joint==‘LeftForeArm’的y_dir为'节点本身LeftForeArm'->'父节点LeftArm',而“joint==‘LeftArm’的y_dir为'节点本身的子节点LeftForeArm'->'节点本身的子节点的字节点LeftHand',而对于joint=='LeftUpLeg'和'LeftLeg'的话,其第三轴x_dir又是固定的'LeftUpLeg'->'Hips',这里我始终无法理解 以上两点,还望赐教!
第一个问题,因为在初始的direction中z轴是垂直leftarm、leftforearm、lefthand平面的,所以设置y_dir就是这个目的,这样插乘出来的z_dir同样垂直这三个节点。至于为什么这样做,我的理解是这样转动少一点吧。我自己试着列了一下方程我发现旋转矩阵都不是唯一的,所以我认为在这个地方按照你说的那样应该也没问题,你可以就把这一部分代码改了试验一下结果看看。
第二个问题,也是一样的,我是觉得矩阵不唯一,但是有一点是要保证的,就是比如我某个节点(假设这个节点只有一个子节点)初始directiron是(1,0,0),那么我后面一定是xyz或者xzy的order,而且x一定是子节点减自己。其他的选取就随便吧。我是这么理解的。当然也有可能不对。
@hujb48 我今天看机器人学的时候发现了我之前一直理解错了。上面的例子rightupleg确实应该是zyx的顺序。在计算rightupleg的子节点rightknee的坐标的时候,需要的是rightupleg处的旋转矩阵,由于rightknee的初始向量是(0,0,-1),因此rightupleg处的旋转矩阵的第三行应该要平行于rightupleg-rightknee。所以应该以此为基准选择zyx的顺序。 而我之前不能理解的Hip处的旋转矩阵其实是近似的旋转。因为实际上lefthip、righthip和spine的位置应该只取决于offset和hip处的旋转矩阵,因此这三个点和hip,他们四个的相对位置应该是固定的,我看了blender里的结果发现好像确实是这样。因此按照上面的逻辑z轴要和spine-hip平行,x的正向轴要和lefthip-hip平行,x的负向轴和hip-righthip平行,这样有三个方程,但是因为这几个点相对位置是固定的,必然不能全部满足,所以作者的代码里选择了z轴与spine-hip平行,然后把另两个方程合在了一起,满足了righthip-lefthip和x轴平行。 我也是刚入门,自己摸索出来的上面结论,可能也还有不正确不到位的地方,兄弟你可以自己也实验看下我说的对不对。
@ZaVang 感谢老哥您的回复以及非常详细讲解,受益匪浅,但我仍弄不懂的两个个问题:
- 就是针对每个joint,其旋转顺序的第一个轴dir的设置都是父节点-子节点的相应设置,这个好理解,那么旋转顺序的第三个轴是如何进行设置的?例如cmu中的“joint==‘LeftForeArm’这个点,顺序是xzy,那么x_dir就是‘LeftHand’->'LeftForeArm', 但是为何y_dir设置成'LeftForeArm'->'LeftArm',而不选择z_dir设置成'LeftForeArm'->'LeftArm',y_dir=None,此时顺序为xyz呢?这个设置应该如何判断?还是说按我说的设置其实本质上没有区别,只是轴的叫法不一样?
- 另外第三个轴到底应该如何进行选择哪些点间向量设置较为合适?因为我看joint==‘LeftForeArm’的y_dir为'节点本身LeftForeArm'->'父节点LeftArm',而“joint==‘LeftArm’的y_dir为'节点本身的子节点LeftForeArm'->'节点本身的子节点的字节点LeftHand',而对于joint=='LeftUpLeg'和'LeftLeg'的话,其第三轴x_dir又是固定的'LeftUpLeg'->'Hips',这里我始终无法理解 以上两点,还望赐教!
第一个问题,因为在初始的direction中z轴是垂直leftarm、leftforearm、lefthand平面的,所以设置y_dir就是这个目的,这样插乘出来的z_dir同样垂直这三个节点。至于为什么这样做,我的理解是这样转动少一点吧。我自己试着列了一下方程我发现旋转矩阵都不是唯一的,所以我认为在这个地方按照你说的那样应该也没问题,你可以就把这一部分代码改了试验一下结果看看。
第二个问题,也是一样的,我是觉得矩阵不唯一,但是有一点是要保证的,就是比如我某个节点(假设这个节点只有一个子节点)初始directiron是(1,0,0),那么我后面一定是xyz或者xzy的order,而且x一定是子节点减自己。其他的选取就随便吧。我是这么理解的。当然也有可能不对。
感谢老哥,您的回复十分有用且帮助很大,我再去进行一些尝试和理解后应该也有更好的体会, 再次感谢!
@hujb48 我重新想了下,关于你上面那个问题应该可以这样解释。我之前想当然觉得都可以随意转动,实际上并不是,就拿LeftArm来说,想象一下真人的情景,我们假设T-pose下手窝朝前,也就是-y方向。那么在实际转动中,可以发现leftarm只能绕z轴和x轴转动。在这里绕着x轴转动其实没啥意义,因为不影响后续的点的位置,如果后续还有手指等节点,我们也可以把旋转归到lefthandt节点上去,所以我们在这里就假设leftarm这块只沿z轴转动。也就是说在任意的情况下,leftarm、leftforearm、lefthand应该都在xy平面上,所以这也解释了为什么要设置leftforearm-leftarm为y轴然后叉乘出z轴了。主要是一直忽略了每个点并不能随意旋转,要从实际人体结构考虑。这样想其他节点的各个轴向的选取就没什么问题了,除了thorax节点那个地方,z轴我认为应该是neck-throax而不是thorax-spine。也可能是我哪里没搞楚。
我之所以想到了这一点,是受到下面这篇文章里的启发。 Tracking and Modelling Motion for Biomechanical Analysis
文章里的3.1介绍了人体的关节大概可以分为几种类型,每种类型有不同的自由度。在文章举的例子里提到了手肘这样的节点自由度是1。具体的你可以看这篇文章了解一下。
@ZaVang 非常感谢,这样的解释非常通透,也进一步帮我理解了轴向选取的问题,再次十分感谢您!文章我会进一步阅读!对我进一步学习人体运动学十分有帮助!
@ZaVang 非常感谢,这样的解释非常通透,也进一步帮我理解了轴向选取的问题,再次十分感谢您!文章我会进一步阅读!对我进一步学习人体运动学十分有帮助!
老哥过奖了,我也是刚入门自学,一起交流进步!
1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?
主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
2.不同关节点定义的旋转顺序的原理是什么?
其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样.
zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.
您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。
感谢!
1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?
主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例 https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L204-L209
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
2.不同关节点定义的旋转顺序的原理是什么?
其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样. https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L171
zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.
您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。
感谢!
您好,请问您这个问题解决了吗
1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?
主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例 https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L204-L209
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
2.不同关节点定义的旋转顺序的原理是什么?
其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样. https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L171
zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.
您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。 感谢!
您好,请问您这个问题解决了吗
嗯嗯,解决了,不过我最后不是用这个repo里的方法的,我使用了另一个库里的基于Jacobi的IK算法,地址在这儿:https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/InverseKinematics.py 应用这个算法,设计好正确的BVH头的话应该可以得到比较准确的旋转角结果。如果想让胯骨可以旋转的话,在设计BVH的时候要把左右胯的骨头单独添加成一个BVH骨骼,这样RightHip和LeftHip的点就有了旋转自由度,可以得到正常的结果。
@gaowei724 @wtnan2003 @hanhailangya @ZaVang 请问大家还有找到精度比较高的 可以转化为.bvh文件保存的方法吗?
1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?
主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例 https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L204-L209
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
2.不同关节点定义的旋转顺序的原理是什么?
其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样. https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L171
zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.
您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。 感谢!
您好,请问您这个问题解决了吗
嗯嗯,解决了,不过我最后不是用这个repo里的方法的,我使用了另一个库里的基于Jacobi的IK算法,地址在这儿:https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/InverseKinematics.py 应用这个算法,设计好正确的BVH头的话应该可以得到比较准确的旋转角结果。如果想让胯骨可以旋转的话,在设计BVH的时候要把左右胯的骨头单独添加成一个BVH骨骼,这样RightHip和LeftHip的点就有了旋转自由度,可以得到正常的结果。
感谢老哥,研究了一下发现还是相对不好理解,您这边是否可以提供一个使用demo,这个算法如何配合骨骼.bvh头以及3D点进行使用
1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?
主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例 https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L204-L209
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
2.不同关节点定义的旋转顺序的原理是什么?
其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样. https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L171
zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.
您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。 感谢!
您好,请问您这个问题解决了吗
嗯嗯,解决了,不过我最后不是用这个repo里的方法的,我使用了另一个库里的基于Jacobi的IK算法,地址在这儿:https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/InverseKinematics.py 应用这个算法,设计好正确的BVH头的话应该可以得到比较准确的旋转角结果。如果想让胯骨可以旋转的话,在设计BVH的时候要把左右胯的骨头单独添加成一个BVH骨骼,这样RightHip和LeftHip的点就有了旋转自由度,可以得到正常的结果。
感谢老哥,研究了一下发现还是相对不好理解,您这边是否可以提供一个使用demo,这个算法如何配合骨骼.bvh头以及3D点进行使用
抱歉我现在在写毕业论文,没时间写详细的demo,只能提供个解决思路,希望能够帮助到您:配置这整个项目的环境是很费事的,但是如果只想运行处理BVH的部分并不困难。 https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/BVH.py 这个里面有个load 方法,你可以用它加载一下它的样例bvh文件: 比如这个 https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ybot.bvh 载入之后是一个Animation类,你可以用里面的postion_global得到3D 关键点,即Forward kinematics功能,之后你可以使用得到的这个关键点测试上面提到的IK算法,譬如使用类BasicJacobianIK的IK算法,他的API是这样: def init(self, animation, positions, iterations=10, silent=True, **kw): animation就是用BVH.load载入的Animation类,positions是你之前得到的3D关键点。
同理,你可以用它来处理你自己的BVH(如果你只有关键点,那么这个BVH的骨骼结构需要自己设计一下,设计好之后我是参考了https://github.com/KevinLTT/video2bvh/blob/master/bvh_skeleton/bvh_helper.py中write_bvh的写法生成的BVH)
1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?
主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例 https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L204-L209
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
2.不同关节点定义的旋转顺序的原理是什么?
其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样. https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L171
zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.
您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。 感谢!
您好,请问您这个问题解决了吗
嗯嗯,解决了,不过我最后不是用这个repo里的方法的,我使用了另一个库里的基于Jacobi的IK算法,地址在这儿:https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/InverseKinematics.py 应用这个算法,设计好正确的BVH头的话应该可以得到比较准确的旋转角结果。如果想让胯骨可以旋转的话,在设计BVH的时候要把左右胯的骨头单独添加成一个BVH骨骼,这样RightHip和LeftHip的点就有了旋转自由度,可以得到正常的结果。
感谢老哥,研究了一下发现还是相对不好理解,您这边是否可以提供一个使用demo,这个算法如何配合骨骼.bvh头以及3D点进行使用
抱歉我现在在写毕业论文,没时间写详细的demo,只能提供个解决思路,希望能够帮助到您:配置这整个项目的环境是很费事的,但是如果只想运行处理BVH的部分并不困难。 https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/BVH.py 这个里面有个load 方法,你可以用它加载一下它的样例bvh文件: 比如这个 https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ybot.bvh 载入之后是一个Animation类,你可以用里面的postion_global得到3D 关键点,即Forward kinematics功能,之后你可以使用得到的这个关键点测试上面提到的IK算法,譬如使用类BasicJacobianIK的IK算法,他的API是这样: def init(self, animation, positions, iterations=10, silent=True, **kw): animation就是用BVH.load载入的Animation类,positions是你之前得到的3D关键点。
同理,你可以用它来处理你自己的BVH(如果你只有关键点,那么这个BVH的骨骼结构需要自己设计一下,设计好之后我是参考了https://github.com/KevinLTT/video2bvh/blob/master/bvh_skeleton/bvh_helper.py中write_bvh的写法生成的BVH)
再次非常感谢老哥您的回复,十分感谢!- -我仔细研究一下,您的回复非常有帮助!
1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性?
主要是根据骨骼的父节点和子节点来定义的, 以右大腿RightUpLeg为例 https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L204-L209
在初始姿态RightLeg->RightUpLeg向量与z轴平行, 所以在计算的时候取其为z轴方向. 同时, 在初始姿态中Hips->RightUpLeg向量与x轴平行, RightLeg->RightUpLeg向量和Hips->RightUpLeg向量构成了xz平面, 所以对二者做叉乘可以求出y轴方向, 最后再对z轴和y轴做叉乘就可以求出x轴方向了, 所以最后的计算顺序是'zyx'.
2.不同关节点定义的旋转顺序的原理是什么?
其实在最后输出bvh的时候关节点的旋转顺序都是zxy, 只是在求旋转角度的时候向量选取的顺序不一样. https://github.com/KevinLTT/video2bvh/blob/87f61358c26bd395bf7311765a0f2d11f4d0a56f/bvh_skeleton/cmu_skeleton.py#L171
zxy的顺序我印象中是最不容易出现万向锁(gimbal lock)问题的一种顺序, 具体的你可以查找一下万向锁相关的资料.
您好。请问,如果初始姿态中RightLeg->RightUpLeg不和z轴平行,这时该如何确定初始旋转矩阵。 我想要通过这个代码把关键点转换成bvh文件,但是在我的场景里,一些关节和它父节点的差向量不和任何一个坐标轴平行。 感谢!
您好,请问您这个问题解决了吗
嗯嗯,解决了,不过我最后不是用这个repo里的方法的,我使用了另一个库里的基于Jacobi的IK算法,地址在这儿:https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/InverseKinematics.py 应用这个算法,设计好正确的BVH头的话应该可以得到比较准确的旋转角结果。如果想让胯骨可以旋转的话,在设计BVH的时候要把左右胯的骨头单独添加成一个BVH骨骼,这样RightHip和LeftHip的点就有了旋转自由度,可以得到正常的结果。
感谢老哥,研究了一下发现还是相对不好理解,您这边是否可以提供一个使用demo,这个算法如何配合骨骼.bvh头以及3D点进行使用
抱歉我现在在写毕业论文,没时间写详细的demo,只能提供个解决思路,希望能够帮助到您:配置这整个项目的环境是很费事的,但是如果只想运行处理BVH的部分并不困难。 https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ik/BVH.py 这个里面有个load 方法,你可以用它加载一下它的样例bvh文件: 比如这个 https://github.com/davrempe/contact-human-dynamics/blob/main/src/skeleton_fitting/ybot.bvh 载入之后是一个Animation类,你可以用里面的postion_global得到3D 关键点,即Forward kinematics功能,之后你可以使用得到的这个关键点测试上面提到的IK算法,譬如使用类BasicJacobianIK的IK算法,他的API是这样: def init(self, animation, positions, iterations=10, silent=True, **kw): animation就是用BVH.load载入的Animation类,positions是你之前得到的3D关键点。
同理,你可以用它来处理你自己的BVH(如果你只有关键点,那么这个BVH的骨骼结构需要自己设计一下,设计好之后我是参考了https://github.com/KevinLTT/video2bvh/blob/master/bvh_skeleton/bvh_helper.py中write_bvh的写法生成的BVH)
大哥我在试你说的方法,我先设计了我的bvh头,然后用bvh.load加载我设计的bvh为anmi,使用BasicJacobianIK(anmi,position),这里的position是我用自己模型跑出来的3d坐标位置,然后进行ik(),得到的结果是很复杂的乱动。你看我的思路有没有问题吗?
作者您好:我有两个问题咨询 1.请问在计算方向余弦矩阵时,所要的两个向量是如何确定的呢?如何选取向量才能保证骨骼旋转欧拉角的正确性? 2.不同关节点定义的旋转顺序的原理是什么? 图形学小白,还望不吝赐教