using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace bbiwarg.Recognition.Tracking { abstract class Tracker where T : TrackableObject where TrackedT : TrackedObject { private float minSimilarity; private List> similarities; protected TrackIDPool idPool; public List TrackedObjects; public Tracker() { reset(); } public void reset() { idPool = new TrackIDPool(); TrackedObjects = new List(); } public void updateFrame(List detectedObjects) { if (TrackedObjects.Count == 0) { addNewTrackedObjects(detectedObjects); } else { updateTrackedObjects(detectedObjects); removeDeletableTrackedObjects(); } } public void updateTrackedObjects(List detectedObjects) { List unasignedTrackedObjects = new List(TrackedObjects); List unasignedDetectedObjects = new List(detectedObjects); createSimilarities(detectedObjects); while (similarities.Count > 0) { Similarity maxSimilarity = similarities[0]; maxSimilarity.TrackedObject.updateFrame(maxSimilarity.DetectedObject); unasignedDetectedObjects.Remove(maxSimilarity.DetectedObject); unasignedTrackedObjects.Remove(maxSimilarity.TrackedObject); removeConcurringSimilarities(maxSimilarity); } addNewTrackedObjects(unasignedDetectedObjects); foreach (TrackedT trackedObject in unasignedTrackedObjects) { trackedObject.updateFrame(null); } } private void addNewTrackedObjects(List detectedObjects) { foreach (T detectedObject in detectedObjects) { TrackedT trackedObject = createTrackedObject(detectedObject); TrackedObjects.Add(trackedObject); } } private void createSimilarities(List detectedObjects) { similarities = new List>(); foreach (TrackedT trackedObject in TrackedObjects) { foreach (T detectedObject in detectedObjects) { float similarityValue = trackedObject.calculateSimilarity(detectedObject); Similarity similarity = new Similarity(trackedObject, detectedObject, similarityValue); if (similarity.Value > 0) similarities.Add(similarity); } } // sort depending on similarity-value similarities.Sort((s1, s2) => s2.Value.CompareTo(s1.Value)); } private void removeConcurringSimilarities(Similarity similarity) { for (int i = similarities.Count - 1; i >= 0; i--) { Similarity s = similarities[i]; if (s.TrackedObject == similarity.TrackedObject || s.DetectedObject == similarity.DetectedObject) similarities.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); } } } protected List getCurrentObjectsWithState(TrackingState state) { List objects = new List(); foreach (TrackedT trackedObject in TrackedObjects) { if (trackedObject.CurrentState == state) objects.Add(trackedObject.CurrentObject); } return objects; } protected abstract TrackedT createTrackedObject(T detectedObject); } }