//! @copydoc FaceTracker::Track((Skeleton[],ColorImageFrame,DepthImageFrame,int) public override void Track(Skeleton[] skeletons, ColorImageFrame colorFrame, DepthImageFrame depthFrame, int nearestUserId) { if (faceTracker == null) { try { faceTracker = new Microsoft.Kinect.Toolkit.FaceTracking.FaceTracker(sensor); } catch (InvalidOperationException) { this.faceTracker = null; UpdateFaceTrackingStatusInternally(FaceTracker.FaceTrackingState.UnableToDetectFaces); return; } } if (colors == null) { colors = new byte[sensor.ColorStream.FramePixelDataLength]; } if (colorFrame == null) { UpdateFaceTrackingStatusInternally(FaceTracker.FaceTrackingState.UnableToDetectFaces); return; } colorFrame.CopyPixelDataTo(colors); if (depths == null) { depths = new short[sensor.DepthStream.FramePixelDataLength]; } if (depthFrame == null) { UpdateFaceTrackingStatusInternally(FaceTracker.FaceTrackingState.UnableToDetectFaces); return; } depthFrame.CopyPixelDataTo(depths); bool?nearUserLooking = null; bool?farUserLooking = null; int nTrackedUsers = 0; foreach (Skeleton skeleton in skeletons) { if (skeleton.TrackingState == SkeletonTrackingState.Tracked) { nTrackedUsers++; var frame = faceTracker.Track(sensor.ColorStream.Format, colors, sensor.DepthStream.Format, depths, skeleton); bool?isLookingToSensor = null; if (frame == null) { if (skeleton.TrackingId == nearestUserId) { nearUserLooking = isLookingToSensor; } else { farUserLooking = isLookingToSensor; } } else { var shape = frame.Get3DShape(); var leftEyeZ = shape[FeaturePoint.AboveMidUpperLeftEyelid].Z; var rightEyeZ = shape[FeaturePoint.AboveMidUpperRightEyelid].Z; var eyeDistZ = Math.Abs(leftEyeZ - rightEyeZ); if (eyeDistZ == 0.0) //special case where, most of the times, indicates an error { isLookingToSensor = null; } else { isLookingToSensor = eyeDistZ <= epsilon; } if (skeleton.TrackingId == nearestUserId) { nearUserLooking = isLookingToSensor; } else { farUserLooking = isLookingToSensor; } } } } FaceTracker.FaceTrackingState trackFaceInternalState = FaceTracker.FaceTrackingState.Disabled; trackFaceInternalState = getFaceTrackState(nTrackedUsers, nearUserLooking, farUserLooking); UpdateFaceTrackingStatusInternally(trackFaceInternalState); }
private FaceTracker.FaceTrackingState getFaceTrackState(int nTrackedUsers, bool?nearUserLooking, bool?farUserLooking) { FaceTracker.FaceTrackingState trackFaceInternalState = FaceTracker.FaceTrackingState.Disabled; if (nTrackedUsers == 0) { FaceTrackingCurrentState = FaceTracker.FaceTrackingState.UnableToDetectFaces; } else { if (nTrackedUsers > 1) { switch (nearUserLooking) { case true: switch (farUserLooking) { case true: trackFaceInternalState = FaceTracker.FaceTrackingState.BothUsersAreLooking; break; case false: case null: trackFaceInternalState = FaceTracker.FaceTrackingState.NearestUserIsLooking; break; } break; case false: case null: switch (farUserLooking) { case true: trackFaceInternalState = FaceTracker.FaceTrackingState.FarthestUserIsLooking; break; case false: trackFaceInternalState = FaceTracker.FaceTrackingState.NeitherUserIsLooking; break; case null: if (nearUserLooking == null) { trackFaceInternalState = FaceTracker.FaceTrackingState.UnableToDetectFaces; } else { trackFaceInternalState = FaceTracker.FaceTrackingState.NeitherUserIsLooking; } break; } break; } } else { switch (nearUserLooking) { case true: trackFaceInternalState = FaceTracker.FaceTrackingState.UserIsLooking; break; case false: trackFaceInternalState = FaceTracker.FaceTrackingState.UserNotLooking; break; case null: trackFaceInternalState = FaceTracker.FaceTrackingState.UnableToDetectFaces; break; } } } return(trackFaceInternalState); }