Tracker.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using bbiwarg.Graphics;
  7. using bbiwarg.Utility;
  8. namespace bbiwarg.Recognition.Tracking
  9. {
  10. public enum TrackingState
  11. {
  12. None,
  13. Detected,
  14. Tracked,
  15. Lost,
  16. }
  17. class Tracker<T> where T : TrackableObject
  18. {
  19. public List<TrackableObjectHistory<T>> Histories { get; private set; }
  20. public List<T> TrackedObjects { get; private set; }
  21. private List<SimilarityContainer<T>> similarities;
  22. private String className;
  23. private LogSubject logSubject;
  24. private int numFramesUntilTracked;
  25. private int numFramesUntilLost;
  26. private float minSimilarityForTracking;
  27. public Tracker(LogSubject logSubject, int numFramesUntilTracked, int numFramesUntilLost, float minSimilarityForTracking)
  28. {
  29. this.className = typeof(T).Name;
  30. this.logSubject = logSubject;
  31. this.numFramesUntilTracked = numFramesUntilTracked;
  32. this.numFramesUntilLost = numFramesUntilLost;
  33. this.minSimilarityForTracking = minSimilarityForTracking;
  34. reset();
  35. }
  36. public void reset()
  37. {
  38. Histories = new List<TrackableObjectHistory<T>>();
  39. TrackedObjects = new List<T>();
  40. }
  41. public void updateFrame(List<T> detectedObjects)
  42. {
  43. if (Histories.Count == 0)
  44. {
  45. foreach (T detectedObject in detectedObjects)
  46. {
  47. TrackableObjectHistory<T> history = new TrackableObjectHistory<T>(numFramesUntilTracked);
  48. history.addObjectToHistory(detectedObject);
  49. addToHistories(history);
  50. }
  51. }
  52. else
  53. {
  54. updateHistories(detectedObjects);
  55. removeLongLostObjects();
  56. }
  57. }
  58. private void updateHistories(List<T> detectedObjects)
  59. {
  60. TrackedObjects = new List<T>();
  61. List<TrackableObjectHistory<T>> unasignedHistories = new List<TrackableObjectHistory<T>>();
  62. foreach (TrackableObjectHistory<T> history in Histories)
  63. unasignedHistories.Add(history);
  64. List<TrackableObject> unasignedDetectedObjects = new List<TrackableObject>();
  65. foreach (T detectedObject in detectedObjects)
  66. unasignedDetectedObjects.Add(detectedObject);
  67. //asign previously tracked objects to their best fits of detectedObjects
  68. createSimilarities(detectedObjects);
  69. while (similarities.Count > 0)
  70. {
  71. SimilarityContainer<T> maxSimilarity = similarities[0];
  72. TrackableObjectHistory<T> history = maxSimilarity.History;
  73. T detectedObject = maxSimilarity.DetectedObject;
  74. history.addObjectToHistory(detectedObject);
  75. TrackedObjects.Add(detectedObject);
  76. unasignedHistories.Remove(history);
  77. unasignedDetectedObjects.Remove(detectedObject);
  78. removeConcurringSimilarities(maxSimilarity);
  79. }
  80. //add new history for each new unasigned detectedObject
  81. foreach (T unasignedDetectedObject in unasignedDetectedObjects)
  82. {
  83. TrackableObjectHistory<T> newHistory = new TrackableObjectHistory<T>(numFramesUntilTracked);
  84. newHistory.addObjectToHistory(unasignedDetectedObject);
  85. addToHistories(newHistory);
  86. }
  87. //add null-object to each unasigned history (didn't find a best fit during this frame -> lost track)
  88. foreach (TrackableObjectHistory<T> unasignedHistory in unasignedHistories)
  89. {
  90. if (unasignedHistory.CurrentState != TrackingState.Lost)
  91. Logger.log(className + " #" + unasignedHistory.ID + " lost", logSubject);
  92. unasignedHistory.addObjectToHistory(null);
  93. }
  94. }
  95. private void createSimilarities(List<T> detectedObjects)
  96. {
  97. similarities = new List<SimilarityContainer<T>>();
  98. foreach (TrackableObjectHistory<T> history in Histories)
  99. {
  100. foreach (T detectedObject in detectedObjects)
  101. {
  102. float similarity = detectedObject.getSimilarity(history.LastObject);
  103. if (similarity > minSimilarityForTracking)
  104. {
  105. SimilarityContainer<T> similarityContainer = new SimilarityContainer<T>(history, detectedObject);
  106. similarities.Add(similarityContainer);
  107. }
  108. }
  109. }
  110. // sort depending on similarity-value
  111. similarities.Sort((fs1, fs2) => fs2.Similarity.CompareTo(fs1.Similarity));
  112. }
  113. private void removeConcurringSimilarities(SimilarityContainer<T> removeSimilarity)
  114. {
  115. for (int i = similarities.Count - 1; i >= 0; i--)
  116. {
  117. SimilarityContainer<T> similarity = similarities[i];
  118. if (similarity.History == removeSimilarity.History || similarity.DetectedObject == removeSimilarity.DetectedObject)
  119. similarities.RemoveAt(i);
  120. }
  121. }
  122. private void removeLongLostObjects()
  123. {
  124. for (int i = Histories.Count - 1; i >= 0; i--)
  125. {
  126. TrackableObjectHistory<T> history = Histories[i];
  127. if (history.CurrentState == TrackingState.Lost && history.NumFramesInCurrentState >= numFramesUntilLost)
  128. {
  129. Histories.RemoveAt(i);
  130. Logger.log(className + " #" + history.ID + " deleted", logSubject);
  131. }
  132. }
  133. }
  134. private void addToHistories(TrackableObjectHistory<T> history)
  135. {
  136. Histories.Add(history);
  137. Logger.log(className + " #" + history.ID + " detected", logSubject);
  138. }
  139. }
  140. }