3

I am reasonably new to Kinect development and I am trying to build a component that allows rotations of Kinect joints. The purpose of this is to manually "fix" any skeleton data I've captured, post capture, where the skeleton starts jumping around.

I am displaying the Kinect skeleton in 3D space using the helix toolkit. I can pause the skeleton stream at any given point and see the matrix values held in the BoneRotations object for the AbsoluteRotation and the HierarchicalRotation.

I've created three sliders which represent an X-axis, Y-axis and Z-axis. I have set their min/max values to something which is relevant to bone's natural movement that is to be manipulated (e.g on the Yaxis, the shoulder doesn't move above roughly 40 degrees). If we take the shoulder (right) joint as an example, I want to be able to apply rotations on each of the axis so that I can change the position of the bone in 3D space. I believe the terminology that relates to this sort of action is forward kinematics.

My questions are:

a) The Kinect SDK gives an absolute and hierarchical matrix for the joint. Which one should I be looking at to manipulate?

b) What does the Quaternion give you that the matrix doesn't?

c) How do I take the 4x4 matrix information and find the angle (either in degrees or radians) for the X-axis, Y-axis and Z-axis?

d) I've seen how to transform 3x3 matrices by multiplying them using a calculation like this:

    Matrix3X3 matrixx = new Matrix3X3();
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            matrixx.elements[(i * 3) + j] = ((R2.elements[i * 3] * R1.elements[j]) + (R2.elements[(i * 3) + 1] * R1.elements[3 + j])) + (R2.elements[(i * 3) + 2] * R1.elements[6 + j]);
        }
    }
    return matrixx;

How do I transform the 4x4 matrix that is given by the Kinect SDK?

More specifically, can I transform the 4x4 matrix on each axis so that I can have a slider for each axis? So how do I apply an X-axis rotation of 10 degrees? I've seen rotations done on 3x3 matrices as follows:

    public static Matrix3D NewRotateAroundX(double radians)
    {
        var matrix = new Matrix3D();
        matrix._matrix[1, 1] = Math.Cos(radians);
        matrix._matrix[1, 2] = Math.Sin(radians);
        matrix._matrix[2, 1] = -(Math.Sin(radians));
        matrix._matrix[2, 2] = Math.Cos(radians);
        return matrix;
    }
    public static Matrix3D NewRotateAroundY(double radians)
    {
        var matrix = new Matrix3D();
        matrix._matrix[0, 0] = Math.Cos(radians);
        matrix._matrix[0, 2] = -(Math.Sin(radians));
        matrix._matrix[2, 0] = Math.Sin(radians);
        matrix._matrix[2, 2] = Math.Cos(radians);
        return matrix;
    }
    public static Matrix3D NewRotateAroundZ(double radians)
    {
        var matrix = new Matrix3D();
        matrix._matrix[0, 0] = Math.Cos(radians);
        matrix._matrix[0, 1] = Math.Sin(radians);
        matrix._matrix[1, 0] = -(Math.Sin(radians));
        matrix._matrix[1, 1] = Math.Cos(radians);
        return matrix;
    }

Thanks for help in advance!

4

1 回答 1

2

这是多个问题,您可能应该将它们分解并分别询问每个问题。

a)我没有玩过 Kinect,但一般来说绝对是相对于世界空间的,而分层是相对于父级的。大多数情况下,您希望相对于其父项移动关节。

b) 这个问题被问错了。四元数表示轴和围绕该轴的旋转,矩阵可以存储此变换以及许多其他类型,包括缩放、平移、倾斜、投影等。

c) 矩阵中前 3 行的前 3 个元素为您提供每个轴,即 X、Y 和 Z(同样在世界空间或父空间中,取决于您正在使用哪个轴)。提取那些,选择你想要的 2 和谷歌“任何 2 条 3D 线之间的角度”(它是它们之间的点积的反余弦)。

d)要使用的正确算法取决于很多事情,有“正确”的方式,然后还有很多其他(更快)的方式也可以工作,如果你能保证你的矩阵总是遵循某些属性,比如仿射等。维基百科有一个关于矩阵乘法的页面,或者你可以阅读我大约 20 年前用代码写的一篇旧文章。后者还应该有助于解释更多关于它们如何工作的信息,并可能向您展示如何做一些您想做的其他事情。

于 2013-12-09T06:31:58.403 回答