Kinect: Calculate Head Pitch, Yaw, Steering Angles
I think I have found a solution, although it is limited, it only works if the Kinect SDK can detect the face, as I am using an object FaceTrackFrame
.
If anyone finds a solution to track more extreme angles where the Kinect SDK fails to detect a face, I would be happier to see one.
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;
}
source to share
I was able to calculate them 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 view code that comes with the SDK and search for the DrawFaceModel function. You can extract code like this in the 1st 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;
Then I put point 0 and point 9 in the next function to get the Step. Then I set the glasses to 120 and 116 to get the angle of the throat.
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 movie, I placed points 0 and 9 again and used the above function again. But I changed
PitchAngle = (Math.Acos(ZDifference / r));
to
RollAngle = Math.Acos(XDifference / r);
source to share