FingerTracker.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. Fingers = new List<Finger>();
  26. }
  27. public void updateTrackedFingers(List<Finger> detectedFingers, OutputImage outputImage)
  28. {
  29. if (FingerHistories.Count == 0)
  30. {
  31. foreach (Finger finger in detectedFingers)
  32. {
  33. FingerHistory fh = new FingerHistory(finger);
  34. FingerHistories.Add(fh);
  35. if (Constants.VerboseFingerTracker) Console.WriteLine("Finger #" + fh.ID + " detected");
  36. }
  37. }
  38. else
  39. {
  40. updateHistories(detectedFingers);
  41. removeLongLostFingers();
  42. }
  43. drawFingers(outputImage);
  44. }
  45. private void updateHistories(List<Finger> detectedFingers)
  46. {
  47. Fingers = new List<Finger>();
  48. List<FingerHistory> unasignedFingerHistories = new List<FingerHistory>();
  49. foreach (FingerHistory fh in FingerHistories)
  50. unasignedFingerHistories.Add(fh);
  51. List<Finger> unasignedDetectedFingers = new List<Finger>();
  52. foreach (Finger f in detectedFingers)
  53. unasignedDetectedFingers.Add(f);
  54. createSimilarities(detectedFingers);
  55. while (similarities.Count > 0)
  56. {
  57. FingerSimilarity maxSimilarity = similarities[0];
  58. FingerHistory fingerHistory = maxSimilarity.fingerHistory;
  59. Finger fingerDetected = maxSimilarity.fingerDetected;
  60. fingerHistory.addFinger(fingerDetected);
  61. Fingers.Add(fingerDetected);
  62. unasignedFingerHistories.Remove(fingerHistory);
  63. unasignedDetectedFingers.Remove(fingerDetected);
  64. removeConcurringFingerSimilarities(maxSimilarity);
  65. }
  66. //add new fingerHistory for each new unmatched finger
  67. foreach (Finger finger in unasignedDetectedFingers)
  68. {
  69. FingerHistory fh = new FingerHistory(finger);
  70. FingerHistories.Add(fh);
  71. if (Constants.VerboseFingerTracker) Console.WriteLine("Finger #" + fh.ID + " detected");
  72. }
  73. //add null finger to TrackedFingers that haven't found a match in this frame (status tracked->lost)
  74. foreach (FingerHistory fh in unasignedFingerHistories)
  75. {
  76. fh.addFinger(null);
  77. }
  78. }
  79. private void createSimilarities(List<Finger> detectedFingers)
  80. {
  81. similarities = new List<FingerSimilarity>();
  82. foreach (FingerHistory fh in FingerHistories)
  83. {
  84. foreach (Finger fingerDetected in detectedFingers)
  85. {
  86. float similarity = fingerDetected.getSimilarity(fh.LastFinger);
  87. if (similarity > Constants.FingerMinSimilarityForTracking)
  88. {
  89. FingerSimilarity fs = new FingerSimilarity();
  90. fs.similarity = similarity;
  91. fs.fingerHistory = fh;
  92. fs.fingerDetected = fingerDetected;
  93. similarities.Add(fs);
  94. }
  95. }
  96. }
  97. similarities.Sort((fs1, fs2) => fs1.similarity.CompareTo(fs2.similarity));
  98. }
  99. private void removeConcurringFingerSimilarities(FingerSimilarity removeSimilarity)
  100. {
  101. for (int i = similarities.Count - 1; i >= 0; i--)
  102. {
  103. FingerSimilarity currentSimilarity = similarities[i];
  104. if (currentSimilarity.fingerHistory == removeSimilarity.fingerHistory || currentSimilarity.fingerDetected == removeSimilarity.fingerDetected)
  105. similarities.RemoveAt(i);
  106. }
  107. }
  108. private void removeFingerDetectedFromSimilarities(Finger removeFinger)
  109. {
  110. for (int i = similarities.Count - 1; i >= 0; i--)
  111. {
  112. if (similarities[i].fingerDetected == removeFinger)
  113. similarities.RemoveAt(i);
  114. }
  115. }
  116. private void removeLongLostFingers()
  117. {
  118. for (int i = FingerHistories.Count - 1; i >= 0; i--)
  119. {
  120. FingerHistory fh = FingerHistories[i];
  121. if (fh.CurrentState == TrackingState.Lost && fh.getNumFramesInCurrentState() >= Constants.FingerNumFramesUntilLost)
  122. {
  123. FingerHistories.RemoveAt(i);
  124. if (Constants.VerboseFingerTracker) Console.WriteLine("Finger #" + fh.ID + " lost");
  125. }
  126. }
  127. }
  128. private void drawFingers(OutputImage outputImage)
  129. {
  130. foreach (Finger finger in Fingers)
  131. {
  132. finger.draw(outputImage, true);
  133. }
  134. }
  135. }
  136. }