123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using bbiwarg.Graphics;
- using bbiwarg.Utility;
- namespace bbiwarg.Recognition.Tracking
- {
- public enum TrackingState
- {
- None,
- Detected,
- Tracked,
- Lost,
- }
- class Tracker<T> where T : TrackableObject
- {
- public List<TrackableObjectHistory<T>> Histories { get; private set; }
- public List<T> TrackedObjects { get; private set; }
- private List<SimilarityContainer<T>> similarities;
- private String className;
- private LogSubject logSubject;
- private int numFramesUntilTracked;
- private int numFramesUntilLost;
- private float minSimilarityForTracking;
- public Tracker(LogSubject logSubject, int numFramesUntilTracked, int numFramesUntilLost, float minSimilarityForTracking)
- {
- this.className = typeof(T).Name;
- this.logSubject = logSubject;
- this.numFramesUntilTracked = numFramesUntilTracked;
- this.numFramesUntilLost = numFramesUntilLost;
- this.minSimilarityForTracking = minSimilarityForTracking;
- reset();
- }
- public void reset()
- {
- Histories = new List<TrackableObjectHistory<T>>();
- TrackedObjects = new List<T>();
- }
- public void updateFrame(List<T> detectedObjects)
- {
- if (Histories.Count == 0)
- {
- foreach (T detectedObject in detectedObjects)
- {
- TrackableObjectHistory<T> history = new TrackableObjectHistory<T>(numFramesUntilTracked);
- history.addObjectToHistory(detectedObject);
- addToHistories(history);
- }
- }
- else
- {
- updateHistories(detectedObjects);
- removeLongLostObjects();
- }
- }
- private void updateHistories(List<T> detectedObjects)
- {
- TrackedObjects = new List<T>();
- List<TrackableObjectHistory<T>> unasignedHistories = new List<TrackableObjectHistory<T>>();
- foreach (TrackableObjectHistory<T> history in Histories)
- unasignedHistories.Add(history);
- List<TrackableObject> unasignedDetectedObjects = new List<TrackableObject>();
- foreach (T detectedObject in detectedObjects)
- unasignedDetectedObjects.Add(detectedObject);
- //asign previously tracked objects to their best fits of detectedObjects
- createSimilarities(detectedObjects);
- while (similarities.Count > 0)
- {
- SimilarityContainer<T> maxSimilarity = similarities[0];
- TrackableObjectHistory<T> history = maxSimilarity.History;
- T detectedObject = maxSimilarity.DetectedObject;
- history.addObjectToHistory(detectedObject);
- TrackedObjects.Add(detectedObject);
- unasignedHistories.Remove(history);
- unasignedDetectedObjects.Remove(detectedObject);
- removeConcurringSimilarities(maxSimilarity);
- }
- //add new history for each new unasigned detectedObject
- foreach (T unasignedDetectedObject in unasignedDetectedObjects)
- {
- TrackableObjectHistory<T> newHistory = new TrackableObjectHistory<T>(numFramesUntilTracked);
- newHistory.addObjectToHistory(unasignedDetectedObject);
- addToHistories(newHistory);
- }
- //add null-object to each unasigned history (didn't find a best fit during this frame -> lost track)
- foreach (TrackableObjectHistory<T> unasignedHistory in unasignedHistories)
- {
- if (unasignedHistory.CurrentState != TrackingState.Lost)
- Logger.log(className + " #" + unasignedHistory.ID + " lost", logSubject);
- unasignedHistory.addObjectToHistory(null);
- }
- }
- private void createSimilarities(List<T> detectedObjects)
- {
- similarities = new List<SimilarityContainer<T>>();
- foreach (TrackableObjectHistory<T> history in Histories)
- {
- foreach (T detectedObject in detectedObjects)
- {
- float similarity = detectedObject.getSimilarity(history.LastObject);
- if (similarity > minSimilarityForTracking)
- {
- SimilarityContainer<T> similarityContainer = new SimilarityContainer<T>(history, detectedObject);
- similarities.Add(similarityContainer);
- }
- }
- }
- // sort depending on similarity-value
- similarities.Sort((fs1, fs2) => fs2.Similarity.CompareTo(fs1.Similarity));
- }
- private void removeConcurringSimilarities(SimilarityContainer<T> removeSimilarity)
- {
- for (int i = similarities.Count - 1; i >= 0; i--)
- {
- SimilarityContainer<T> similarity = similarities[i];
- if (similarity.History == removeSimilarity.History || similarity.DetectedObject == removeSimilarity.DetectedObject)
- similarities.RemoveAt(i);
- }
- }
- private void removeLongLostObjects()
- {
- for (int i = Histories.Count - 1; i >= 0; i--)
- {
- TrackableObjectHistory<T> history = Histories[i];
- if (history.CurrentState == TrackingState.Lost && history.NumFramesInCurrentState >= numFramesUntilLost)
- {
- Histories.RemoveAt(i);
- Logger.log(className + " #" + history.ID + " deleted", logSubject);
- }
- }
- }
- private void addToHistories(TrackableObjectHistory<T> history)
- {
- Histories.Add(history);
- Logger.log(className + " #" + history.ID + " detected", logSubject);
- }
- }
- }
|