FingerTracker.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using bbiwarg.Images;
  8. using bbiwarg.Graphics;
  9. namespace bbiwarg.Recognition.FingerRecognition
  10. {
  11. struct FingerSimilarity
  12. {
  13. public float similarity;
  14. public FingerHistory fingerHistory;
  15. public Finger fingerDetected;
  16. }
  17. class FingerTracker
  18. {
  19. public List<FingerHistory> FingerHistories { get; private set; }
  20. public List<Finger> Fingers { get; private set; }
  21. private List<FingerSimilarity> similarities;
  22. public FingerTracker()
  23. {
  24. FingerHistories = new List<FingerHistory>();
  25. }
  26. public void updateTrackedFingers(List<Finger> detectedFingers)
  27. {
  28. if (FingerHistories.Count == 0)
  29. {
  30. foreach (Finger finger in detectedFingers)
  31. FingerHistories.Add(new FingerHistory(finger));
  32. }
  33. else
  34. {
  35. updateHistories(detectedFingers);
  36. removeLongLostFingers();
  37. }
  38. }
  39. private void updateHistories(List<Finger> detectedFingers)
  40. {
  41. Fingers = new List<Finger>();
  42. List<FingerHistory> unasignedFingerHistories = new List<FingerHistory>();
  43. foreach (FingerHistory fh in FingerHistories)
  44. unasignedFingerHistories.Add(fh);
  45. List<Finger> unasignedDetectedFingers = new List<Finger>();
  46. foreach (Finger f in detectedFingers)
  47. unasignedDetectedFingers.Add(f);
  48. createSimilarities(detectedFingers);
  49. while (similarities.Count > 0)
  50. {
  51. FingerSimilarity maxSimilarity = similarities[0];
  52. FingerHistory fingerHistory = maxSimilarity.fingerHistory;
  53. Finger fingerDetected = maxSimilarity.fingerDetected;
  54. fingerHistory.addFinger(fingerDetected);
  55. Fingers.Add(fingerDetected);
  56. unasignedFingerHistories.Remove(fingerHistory);
  57. unasignedDetectedFingers.Remove(fingerDetected);
  58. removeConcurringFingerSimilarities(maxSimilarity);
  59. }
  60. //add new fingerHistory for each new unmatched finger
  61. foreach (Finger f in unasignedDetectedFingers)
  62. {
  63. FingerHistories.Add(new FingerHistory(f));
  64. }
  65. //add null finger to TrackedFingers that haven't found a match in this frame (status tracked->lost)
  66. foreach (FingerHistory fh in unasignedFingerHistories)
  67. {
  68. fh.addFinger(null);
  69. }
  70. }
  71. private void createSimilarities(List<Finger> detectedFingers)
  72. {
  73. similarities = new List<FingerSimilarity>();
  74. foreach (FingerHistory fh in FingerHistories)
  75. {
  76. foreach (Finger fingerDetected in detectedFingers)
  77. {
  78. float similarity = fingerDetected.getSimilarity(fh.LastFinger);
  79. if (similarity > Constants.FingerMinSimilarityForTracking)
  80. {
  81. FingerSimilarity fs = new FingerSimilarity();
  82. fs.similarity = similarity;
  83. fs.fingerHistory = fh;
  84. fs.fingerDetected = fingerDetected;
  85. similarities.Add(fs);
  86. }
  87. }
  88. }
  89. similarities.Sort((fs1, fs2) => fs1.similarity.CompareTo(fs2.similarity));
  90. }
  91. private void removeConcurringFingerSimilarities(FingerSimilarity removeSimilarity)
  92. {
  93. for (int i = similarities.Count - 1; i >= 0; i--)
  94. {
  95. FingerSimilarity currentSimilarity = similarities[i];
  96. if (currentSimilarity.fingerHistory == removeSimilarity.fingerHistory || currentSimilarity.fingerDetected == removeSimilarity.fingerDetected)
  97. similarities.RemoveAt(i);
  98. }
  99. }
  100. private void removeFingerDetectedFromSimilarities(Finger removeFinger)
  101. {
  102. for (int i = similarities.Count - 1; i >= 0; i--)
  103. {
  104. if (similarities[i].fingerDetected == removeFinger)
  105. similarities.RemoveAt(i);
  106. }
  107. }
  108. private void removeLongLostFingers()
  109. {
  110. for (int i = FingerHistories.Count - 1; i >= 0; i--)
  111. {
  112. FingerHistory tf = FingerHistories[i];
  113. if (tf.CurrentState == TrackingState.Lost && tf.getNumFramesInCurrentState() >= Constants.FingerNumFramesUntilLost)
  114. FingerHistories.RemoveAt(i);
  115. }
  116. }
  117. }
  118. }