Kinect SDK - Transform the rotation of an angle by degrees

2.1k views Asked by At

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!

1

There are 1 answers

3
Mark Feldman On BEST ANSWER

This is multiple questions and you should probably break them down and ask each one separately.

a) I haven't played with Kinect but generally speaking absolute is relative to world space and hierarchical is relative to the parent. Most of the time you want to move a joint relative to its parent.

b) This question is asked the wrong way round. A quaternion represents an axis and a rotation about that axis, a matrix can store this transform plus many other types including scale, translate, skew, projection etc.

c) The first 3 elements of the first 3 rows in a matrix give you each axis i.e. X, Y, and Z (again in either world space or parent space, depending on which one you're working with). Extract those, pick the 2 you're after and Google "angle between any 2 3D lines" (it's the inverse cosine of the dot product between them).

d) The correct algorithm to use depends on a number of things, there's the "correct" way and then there are a lot of other (faster) ways that will also work if you can guarantee that your matrices will always follow certain properties like being affine etc. Wikipedia has a page about matrix multiplication or you can read an old article I wrote almost 20 years ago with code. The latter should also help explain a bit more about how they work and maybe show you how to do some of the other things you'll looking to do.