using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using bbiwarg.Recognition.Tracking;
using bbiwarg.Recognition.HandRecognition;
using bbiwarg.Utility;
namespace bbiwarg.Recognition.PalmRecognition
{
///
/// Represents a palm that ist tracked for several frames.
///
class TrackedPalm : TrackedObject
{
///
/// the kalman filter for the wrist upper prediction
///
private Kalman2DPositionFilter wristUpperKalman;
///
/// the kalman filter for the wrist lower prediction
///
private Kalman2DPositionFilter wristLowerKalman;
///
/// the kalman filter for the fingers upper prediction
///
private Kalman2DPositionFilter fingersUpperKalman;
///
/// the kalman filter for the fingers lower prediction
///
private Kalman2DPositionFilter fingersLowerKalman;
///
/// the predicted position of the wrist upper
///
public Vector2D WristUpperPrediction { get { return wristUpperKalman.getPrediction(); } }
///
/// the predicted position of the wrist lower
///
public Vector2D WristLowerPrediction { get { return wristLowerKalman.getPrediction(); } }
///
/// the predicted position of the fingers upper
///
public Vector2D FingersUpperPrediction { get { return fingersUpperKalman.getPrediction(); } }
///
/// the predicted position of the fingers lower
///
public Vector2D FingersLowerPrediction { get { return fingersLowerKalman.getPrediction(); } }
///
/// the optimized palm (using predicted palm points)
///
public Palm OptimizedPalm { get; private set; }
///
/// 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 statechange, updates the palm point predictions and the optimized 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);
}
}
///
/// Updates the optimized palm by creating a new palm with the predicted palm points
///
///
private void updateOptimizedPalm(Palm detectedPalm)
{
OptimizedPalm = new Palm(detectedPalm.Hand, detectedPalm.ThumbDefect, detectedPalm.HandSide, WristUpperPrediction, FingersUpperPrediction, FingersLowerPrediction, WristLowerPrediction);
}
///
/// logs the state change
///
private void logStateChange()
{
String stateAsString = CurrentState.ToString().ToLower();
Logger.log(String.Format("Palm #{0} {1}", this.ID, stateAsString), LogSubject.PalmTracker);
}
}
}