TrackedFinger.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. using BBIWARG.Recognition.Tracking;
  2. using BBIWARG.Utility;
  3. using System;
  4. using System.Collections.Generic;
  5. namespace BBIWARG.Recognition.FingerRecognition
  6. {
  7. /// <summary>
  8. /// Represents a finger that is tracked for several frames.
  9. /// </summary>
  10. internal class TrackedFinger : TrackedObject<Finger>
  11. {
  12. /// <summary>
  13. /// the kalman filter for the hand point prediction
  14. /// </summary>
  15. private Kalman2DPositionFilter handPointKalman;
  16. /// <summary>
  17. /// list of last directions (used to correct finger directions if they differ from average)
  18. /// </summary>
  19. private List<Vector2D> lastRawDirections;
  20. /// <summary>
  21. /// the kalman filter for the tip point prediction
  22. /// </summary>
  23. private Kalman2DPositionFilter tipPointKalman;
  24. /// <summary>
  25. /// predicted position of the hand point
  26. /// </summary>
  27. public Vector2D HandPointPrediction { get { return handPointKalman.getPrediction(); } }
  28. /// <summary>
  29. /// the average direction of the last fingers
  30. /// </summary>
  31. public Vector2D MeanDirection { get { return Vector2D.mean(lastRawDirections); } }
  32. /// <summary>
  33. /// predicted position of the tip point
  34. /// </summary>
  35. public Vector2D TipPointPrediction { get { return tipPointKalman.getPrediction(); } }
  36. /// <summary>
  37. /// Initializes a new instance of the TrackedFinger class.
  38. /// </summary>
  39. /// <param name="id">The track ID.</param>
  40. /// <param name="detectedFinger">The initial detected finger.</param>
  41. /// <param name="numFramesDetectedUntilTracked">The number of consecutive frames detected until the finger is considered to be tracked.</param>
  42. /// <param name="numFramesLostUntilDeleted">The number of consecutive frames lost until the finger is considered to be deleted.</param>
  43. public TrackedFinger(int id, Finger detectedFinger, int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted)
  44. : base(id, detectedFinger, numFramesDetectedUntilTracked, numFramesLostUntilDeleted)
  45. {
  46. tipPointKalman = new Kalman2DPositionFilter(Parameters.FingermXX, Parameters.FingermXY, Parameters.FingermYY);
  47. tipPointKalman.setInitialPosition(detectedFinger.TipPoint);
  48. handPointKalman = new Kalman2DPositionFilter(Parameters.FingermXX, Parameters.FingermXY, Parameters.FingermYY);
  49. handPointKalman.setInitialPosition(detectedFinger.HandPoint);
  50. lastRawDirections = new List<Vector2D>();
  51. logStateChange();
  52. }
  53. /// <summary>
  54. /// Indicates whether a newly detected finger should be reverse (direction differs from average direction of previous fingers).
  55. /// </summary>
  56. /// <param name="detectedFinger">the detected finger</param>
  57. /// <returns>whether the fingers direction matches to the direction of the previous fingers</returns>
  58. public bool shouldFingerBeReversed(Finger detectedFinger)
  59. {
  60. Vector2D meanDirection = Vector2D.mean(lastRawDirections);
  61. return meanDirection.isInOppositeDirection(detectedFinger.Direction);
  62. }
  63. /// <summary>
  64. /// Updates the tracked finger with the given finger, logs the state change, corrects the finger's direction if needed and updates the position predictions (kalman filters).
  65. /// </summary>
  66. /// <param name="detectedFinger">The detected finger.</param>
  67. public override void updateFrame(Finger detectedFinger)
  68. {
  69. base.updateFrame(detectedFinger);
  70. if (NumFramesInCurrentState == 1)
  71. logStateChange();
  72. if (detectedFinger != null)
  73. {
  74. Vector2D rawDirection = detectedFinger.Direction;
  75. if (shouldFingerBeReversed(detectedFinger))
  76. detectedFinger.reverse();
  77. tipPointKalman.getCorrectedPosition(detectedFinger.TipPoint);
  78. handPointKalman.getCorrectedPosition(detectedFinger.HandPoint);
  79. lastRawDirections.Add(rawDirection);
  80. if (lastRawDirections.Count == Parameters.FingerTrackerNumDirectionsForMeanDirection)
  81. lastRawDirections.RemoveAt(0);
  82. }
  83. }
  84. /// <summary>
  85. /// logs the state change
  86. /// </summary>
  87. private void logStateChange()
  88. {
  89. String stateAsString = CurrentState.ToString().ToLower();
  90. Logger.log(String.Format("Finger #{0} {1}", this.ID, stateAsString), LogSubject.FingerTracker);
  91. }
  92. }
  93. }