123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- 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 = 0,
- Detected = 1,
- Tracked = 2,
- Lost = 3,
- Delete = 4
- }
- abstract 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 int numFramesDetectedUntilTracked;
- private int numFramesLostUntilDeleted;
- private float minSimilarityForTracking;
- public Tracker(int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted, float minSimilarityForTracking)
- {
- this.numFramesDetectedUntilTracked = numFramesDetectedUntilTracked;
- this.numFramesLostUntilDeleted = numFramesLostUntilDeleted;
- 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 = createNewHistory();
- history.addObjectToHistory(detectedObject);
- Histories.Add(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 = createNewHistory();
- newHistory.addObjectToHistory(unasignedDetectedObject);
- Histories.Add(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)
- {
- 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)
- {
- SimilarityContainer<T> similarityContainer = new SimilarityContainer<T>(history, detectedObject);
- if (similarityContainer.Similarity > minSimilarityForTracking)
- {
- 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.Delete)
- {
- Histories.RemoveAt(i);
- }
- }
- }
- private TrackableObjectHistory<T> createNewHistory()
- {
- TrackableObjectHistory<T> history = new TrackableObjectHistory<T>(numFramesDetectedUntilTracked, numFramesLostUntilDeleted);
- history.Detected += onDetect;
- history.Tracked += onTrack;
- history.Retracked += onRetrack;
- history.Lost += onLoose;
- history.Deleted += onDelete;
- return history;
- }
- protected abstract void onDetect(object sender, EventArgs e);
- protected abstract void onTrack(object sender, EventArgs e);
- protected abstract void onRetrack(object sender, EventArgs e);
- protected abstract void onLoose(object sender, EventArgs e);
- protected abstract void onDelete(object sender, EventArgs e);
- }
- }
|