FingerTracker.cs 6.1 KB

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