|
@@ -3,162 +3,119 @@ 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
|
|
|
+ abstract class Tracker<T, TrackedT>
|
|
|
+ where T : TrackableObject
|
|
|
+ where TrackedT : TrackedObject<T>
|
|
|
{
|
|
|
- None = 0,
|
|
|
- Detected = 1,
|
|
|
- Tracked = 2,
|
|
|
- Lost = 3,
|
|
|
- Delete = 4
|
|
|
- }
|
|
|
+ private float minSimilarity;
|
|
|
+ private List<Similarity<T, TrackedT>> similarities;
|
|
|
+ protected TrackIDPool idPool;
|
|
|
+
|
|
|
+ public List<TrackedT> TrackedObjects;
|
|
|
|
|
|
- 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;
|
|
|
|
|
|
+ public Tracker(float minSimilarity)
|
|
|
+ {
|
|
|
+ this.minSimilarity = minSimilarity;
|
|
|
reset();
|
|
|
}
|
|
|
|
|
|
public void reset()
|
|
|
{
|
|
|
- Histories = new List<TrackableObjectHistory<T>>();
|
|
|
- TrackedObjects = new List<T>();
|
|
|
+ idPool = new TrackIDPool();
|
|
|
+ TrackedObjects = new List<TrackedT>();
|
|
|
}
|
|
|
|
|
|
public void updateFrame(List<T> detectedObjects)
|
|
|
{
|
|
|
- if (Histories.Count == 0)
|
|
|
+ if (TrackedObjects.Count == 0)
|
|
|
{
|
|
|
- foreach (T detectedObject in detectedObjects)
|
|
|
- {
|
|
|
- TrackableObjectHistory<T> history = createNewHistory();
|
|
|
- history.addObjectToHistory(detectedObject);
|
|
|
- Histories.Add(history);
|
|
|
- }
|
|
|
+ addNewTrackedObjects(detectedObjects);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- updateHistories(detectedObjects);
|
|
|
- removeLongLostObjects();
|
|
|
+ updateTrackedObjects(detectedObjects);
|
|
|
+ removeDeletableTrackedObjects();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void updateHistories(List<T> detectedObjects)
|
|
|
+ public void updateTrackedObjects(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<TrackedT> unasignedTrackedObjects = new List<TrackedT>(TrackedObjects);
|
|
|
+ List<T> unasignedDetectedObjects = new List<T>(detectedObjects);
|
|
|
|
|
|
- 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);
|
|
|
+ while (similarities.Count > 0) {
|
|
|
+ Similarity<T, TrackedT> maxSimilarity = similarities[0];
|
|
|
+ maxSimilarity.TrackedObject.updateFrame(maxSimilarity.DetectedObject);
|
|
|
+
|
|
|
+ unasignedDetectedObjects.Remove(maxSimilarity.DetectedObject);
|
|
|
+ unasignedTrackedObjects.Remove(maxSimilarity.TrackedObject);
|
|
|
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);
|
|
|
+
|
|
|
+ addNewTrackedObjects(unasignedDetectedObjects);
|
|
|
+
|
|
|
+ foreach (TrackedT trackedObject in unasignedTrackedObjects) {
|
|
|
+ trackedObject.updateFrame(null);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- //add null-object to each unasigned history (didn't find a best fit during this frame -> lost track)
|
|
|
- foreach (TrackableObjectHistory<T> unasignedHistory in unasignedHistories)
|
|
|
+ private void addNewTrackedObjects(List<T> detectedObjects)
|
|
|
+ {
|
|
|
+ foreach (T detectedObject in detectedObjects)
|
|
|
{
|
|
|
- unasignedHistory.addObjectToHistory(null);
|
|
|
+ TrackedT trackedObject = createTrackedObject(detectedObject);
|
|
|
+ TrackedObjects.Add(trackedObject);
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
- private void createSimilarities(List<T> detectedObjects)
|
|
|
- {
|
|
|
- similarities = new List<SimilarityContainer<T>>();
|
|
|
+ private void createSimilarities(List<T> detectedObjects) {
|
|
|
+ similarities = new List<Similarity<T, TrackedT>>();
|
|
|
|
|
|
- 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);
|
|
|
- }
|
|
|
+ foreach (TrackedT trackedObject in TrackedObjects) {
|
|
|
+ foreach (T detectedObject in detectedObjects) {
|
|
|
+ float similarityValue = trackedObject.getSimilarity(detectedObject);
|
|
|
+ Similarity<T, TrackedT> similarity = new Similarity<T,TrackedT>(trackedObject, detectedObject, similarityValue);
|
|
|
+ if (similarity.Value > minSimilarity)
|
|
|
+ similarities.Add(similarity);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// sort depending on similarity-value
|
|
|
- similarities.Sort((fs1, fs2) => fs2.Similarity.CompareTo(fs1.Similarity));
|
|
|
+ similarities.Sort((s1, s2) => s2.Value.CompareTo(s1.Value));
|
|
|
}
|
|
|
|
|
|
- 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)
|
|
|
+ private void removeConcurringSimilarities(Similarity<T, TrackedT> similarity) {
|
|
|
+ for (int i = similarities.Count - 1; i >= 0; i--) {
|
|
|
+ Similarity<T, TrackedT> s = similarities[i];
|
|
|
+ if (s.TrackedObject == similarity.TrackedObject || s.DetectedObject == similarity.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 void removeDeletableTrackedObjects() {
|
|
|
+ for (int i = TrackedObjects.Count - 1; i >= 0; i--) {
|
|
|
+ TrackedT trackedObject = TrackedObjects[i];
|
|
|
+ if (trackedObject.CurrentState == TrackingState.Deleted) {
|
|
|
+ idPool.setIDUnused(trackedObject.ID);
|
|
|
+ TrackedObjects.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 List<T> getCurrentObjectsWithState(TrackingState state) {
|
|
|
+ List<T> objects = new List<T>();
|
|
|
+ foreach (TrackedT trackedObject in TrackedObjects) {
|
|
|
+ if (trackedObject.CurrentState == state)
|
|
|
+ objects.Add(trackedObject.CurrentObject);
|
|
|
+ }
|
|
|
+ return objects;
|
|
|
+ }
|
|
|
|
|
|
- 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);
|
|
|
+ protected abstract TrackedT createTrackedObject(T detectedObject);
|
|
|
}
|
|
|
}
|