smukov
smukov

Reputation: 625

Kinect: Calculate head's pitch, yaw, roll angles

I am trying to use Kinect sensor and SDK to calculate the orientation of user's head but I wasn't able to find any good help for this on google. Does anybody have any good sample, tutorial or something like that that might help me?

Upvotes: 3

Views: 5143

Answers (2)

smukov
smukov

Reputation: 625

I think that I have found a solution although it's limited, it works only if the Kinect SDK can detect the face since I'm using the FaceTrackFrame object.

If somebody finds a solution to track more extreme angles when Kinect SDK is unable to detect a face I'd be more then happy to see it.

My solution looks something like this:

       FaceTrackFrame faceFrame = faceTracker.Track(
            kinectSensor.ColorStream.Format, colorPixelData,
            kinectSensor.DepthStream.Format, depthPixelData, skeleton);

        // Only works if face is detected
        if (faceFrame.TrackSuccessful)
        {
            txtTracked.Content = "TRACKED";
            txtRoll.Content = faceFrame.Rotation.Z;
            txtPitch.Content = faceFrame.Rotation.X;
            txtYaw.Content = faceFrame.Rotation.Y;
        }

Upvotes: 2

difurious
difurious

Reputation: 1542

I managed to calculate these manually using the depth data from the image.

First you need to get the depth point

    private EnumIndexableCollection<FeaturePoint, Vector3DF> depthPoints;

Then if you look at the FaceTracking viewer code that comes with the SDK and search for the DrawFaceModel function. You can extract the code like this in the 1st for loop.

    faceModelPts3D.Add(new Point3D(this.depthPoints[i].X + 0.5f, this.depthPoints[i].Y + 0.5f, this.depthPoints[i].Z + 0.5f));
    FaceDataPoints.DepthXPointInfo[i] = this.depthPoints[i].X;
    FaceDataPoints.DepthYPointInfo[i] = this.depthPoints[i].Y;
    FaceDataPoints.DepthZPointInfo[i] = this.depthPoints[i].Z;

I then placed point 0 and point 9 into the following function to obtain the Pitch. I then put the Points 120 and 116 in to obtain the yawn angle.

    public static double FacePitch(double FirstXPos, double FirstYPos, double FirstZPos, double SecXPos, double SecYPos, double SecZPos)
    {
        double PitchAngle = 0;
        double r = 0;
        double XDifference, YDifference, ZDifference = 0;
        double DifferenceSquared = 0;

        XDifference = FirstXPos - SecXPos;//Calculates distance from Points 
        YDifference = FirstYPos - SecYPos;
        ZDifference = FirstZPos - SecZPos;

        DifferenceSquared = Math.Pow(XDifference, 2) + Math.Pow(YDifference, 2) + Math.Pow(ZDifference, 2);

        r = Math.Sqrt(DifferenceSquared);

        PitchAngle = (Math.Acos(ZDifference / r));

        PitchAngle = ((PitchAngle * 180 / Math.PI) - 90) * -1; //Converts to Degrees as easier to recognise visually 

        return PitchAngle;
    }

for the roll i placed point 0 and 9 in again and used the above function again But i changed

PitchAngle = (Math.Acos(ZDifference / r));

to

RollAngle = Math.Acos(XDifference / r);

Upvotes: 1

Related Questions