TrackedFinger.cs 4.7 KB

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