using BBIWARG.Recognition.Tracking; using BBIWARG.Utility; using System; namespace BBIWARG.Recognition.PalmRecognition { /// /// Represents a palm that is tracked for several frames. /// internal class TrackedPalm : TrackedObject { /// /// the kalman filter for the fingers lower prediction /// private Kalman2DPositionFilter fingersLowerKalman; /// /// the kalman filter for the fingers upper prediction /// private Kalman2DPositionFilter fingersUpperKalman; /// /// the kalman filter for the wrist lower prediction /// private Kalman2DPositionFilter wristLowerKalman; /// /// the kalman filter for the wrist upper prediction /// private Kalman2DPositionFilter wristUpperKalman; /// /// the predicted position of the fingers lower /// public Vector2D FingersLowerPrediction { get { return fingersLowerKalman.getPrediction(); } } /// /// the predicted position of the fingers upper /// public Vector2D FingersUpperPrediction { get { return fingersUpperKalman.getPrediction(); } } /// /// the optimized palm (using predicted palm points) /// public Palm OptimizedPalm { get; private set; } /// /// the predicted position of the wrist lower /// public Vector2D WristLowerPrediction { get { return wristLowerKalman.getPrediction(); } } /// /// the predicted position of the wrist upper /// public Vector2D WristUpperPrediction { get { return wristUpperKalman.getPrediction(); } } /// /// Initializes a new instance of the TrackedPalm class. /// /// The track ID. /// The detected palm. /// The number of consecutive frames detected until the palm is considered tracked. /// The number of consecutive frames lost until the palm is deleted. public TrackedPalm(int id, Palm detectedPalm, int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted) : base(id, detectedPalm, numFramesDetectedUntilTracked, numFramesLostUntilDeleted) { wristUpperKalman = new Kalman2DPositionFilter(Parameters.PalmmXX, Parameters.PalmmXY, Parameters.PalmmYY); wristLowerKalman = new Kalman2DPositionFilter(Parameters.PalmmXX, Parameters.PalmmXY, Parameters.PalmmYY); fingersUpperKalman = new Kalman2DPositionFilter(Parameters.PalmmXX, Parameters.PalmmXY, Parameters.PalmmYY); fingersLowerKalman = new Kalman2DPositionFilter(Parameters.PalmmXX, Parameters.PalmmXY, Parameters.PalmmYY); wristUpperKalman.setInitialPosition(detectedPalm.WristUpper); wristLowerKalman.setInitialPosition(detectedPalm.WristLower); fingersUpperKalman.setInitialPosition(detectedPalm.FingersUpper); fingersLowerKalman.setInitialPosition(detectedPalm.FingersLower); updateOptimizedPalm(detectedPalm); logStateChange(); } /// /// Updates the tracked palm with the given palm, logs the state change, updates the palm point predictions and the optimized palm. /// /// the detected palm public override void updateFrame(Palm detectedPalm) { base.updateFrame(detectedPalm); if (NumFramesInCurrentState == 1) logStateChange(); if (detectedPalm != null) { wristUpperKalman.getCorrectedPosition(detectedPalm.WristUpper); wristLowerKalman.getCorrectedPosition(detectedPalm.WristLower); fingersUpperKalman.getCorrectedPosition(detectedPalm.FingersUpper); fingersLowerKalman.getCorrectedPosition(detectedPalm.FingersLower); updateOptimizedPalm(detectedPalm); } } /// /// logs the state change /// private void logStateChange() { String stateAsString = CurrentState.ToString().ToLower(); Logger.log(String.Format("Palm #{0} {1}", this.ID, stateAsString), LogSubject.PalmTracker); } /// /// Updates the optimized palm by creating a new palm with the predicted palm points /// /// the detected palm private void updateOptimizedPalm(Palm detectedPalm) { OptimizedPalm = new Palm(detectedPalm.Hand, detectedPalm.ThumbDefect, detectedPalm.HandSide, WristUpperPrediction, FingersUpperPrediction, FingersLowerPrediction, WristLowerPrediction); OptimizedPalm.setTracked(ID); } } }