TrackedFinger.cs 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. class TrackedFinger : TrackedObject<Finger>
  11. {
  12. private Kalman2DPositionFilter tipPointKalman;
  13. private Kalman2DPositionFilter handPointKalman;
  14. private List<Vector2D> lastRawDirections;
  15. public Vector2D TipPointPrediction { get { return tipPointKalman.getPrediction(); } }
  16. public Vector2D HandPointPrediction { get { return handPointKalman.getPrediction(); } }
  17. public TrackedFinger(int id, Finger detectedFinger, int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted)
  18. : base(id, detectedFinger, numFramesDetectedUntilTracked, numFramesLostUntilDeleted)
  19. {
  20. tipPointKalman = new Kalman2DPositionFilter(Parameters.FingermXX, Parameters.FingermXY, Parameters.FingermYY);
  21. tipPointKalman.setInitialPosition(detectedFinger.TipPoint);
  22. handPointKalman = new Kalman2DPositionFilter(Parameters.FingermXX, Parameters.FingermXY, Parameters.FingermYY);
  23. handPointKalman.setInitialPosition(detectedFinger.HandPoint);
  24. lastRawDirections = new List<Vector2D>();
  25. logStateChange();
  26. }
  27. public override void updateFrame(Finger detectedFinger)
  28. {
  29. base.updateFrame(detectedFinger);
  30. if (NumFramesInCurrentState == 1)
  31. logStateChange();
  32. if (detectedFinger != null)
  33. {
  34. Vector2D rawDirection = detectedFinger.Direction;
  35. if (shouldFingerBeReversed(detectedFinger))
  36. detectedFinger.reverse();
  37. tipPointKalman.getCorrectedPosition(detectedFinger.TipPoint);
  38. handPointKalman.getCorrectedPosition(detectedFinger.HandPoint);
  39. lastRawDirections.Add(rawDirection);
  40. if (lastRawDirections.Count == Parameters.FingerTrackerNumDirectionsForReverseCheck)
  41. lastRawDirections.RemoveAt(0);
  42. }
  43. }
  44. public override float calculateSimilarity(Finger detectedFinger)
  45. {
  46. Vector2D tip, hand;
  47. if (shouldFingerBeReversed(detectedFinger))
  48. {
  49. tip = detectedFinger.HandPoint;
  50. hand = detectedFinger.TipPoint;
  51. }
  52. else {
  53. tip = detectedFinger.TipPoint;
  54. hand = detectedFinger.HandPoint;
  55. }
  56. //tip position
  57. float tipPointDistance = tip.getDistanceTo(TipPointPrediction);
  58. float tipPointSimilarity = Math.Max(0, 1 - tipPointDistance / Parameters.ImageDiagonalLength);
  59. //hand position
  60. float handPointDistance = hand.getDistanceTo(HandPointPrediction);
  61. float handPointSimilarity = Math.Max(0, 1 - handPointDistance / Parameters.ImageDiagonalLength);
  62. return tipPointSimilarity * handPointSimilarity;
  63. }
  64. private bool shouldFingerBeReversed(Finger detectedFinger) {
  65. Vector2D meanDirection = Vector2D.mean(lastRawDirections);
  66. return (meanDirection.getAngleBetween(detectedFinger.Direction) > Math.PI / 4);
  67. }
  68. private void logStateChange()
  69. {
  70. String stateAsString = CurrentState.ToString().ToLower();
  71. Logger.log(String.Format("Finger #{0} {1}", this.ID, stateAsString), LogSubject.FingerTracker);
  72. }
  73. }
  74. }