namespace bbiwarg.Recognition.Tracking { /// /// The possible tracking state values /// public enum TrackingState { Undefined = 0, Detected = 1, Tracked = 2, Lost = 3, Deleted = 4 } /// /// A tracked object is identified by severall TrackableObjects in different frames that have a high similiarity value and are considered to represent the same object over time. /// /// The type of the trackable object public abstract class TrackedObject where T : TrackableObject { /// /// the number of consecutive frames the object has to be detected until its state changes to tracked /// private int numFramesDetectedUntilTracked; /// /// the number of consecutive frames the object has to be lost until its state changes to delete /// private int numFramesLostUntilDeleted; /// /// indicates wether the object has been tracked before /// private bool wasTrackedBefore; /// /// a reference to the current TrackableObject /// public T CurrentObject { get; private set; } /// /// the current tracking state /// public TrackingState CurrentState { get; private set; } /// /// the objects track id /// public int ID { get; private set; } /// /// a reference to the last TrackableObject /// public T LastObject { get; private set; } /// /// the number of consecutive frames in the current state /// public int NumFramesInCurrentState { get; private set; } /// /// the previous tracking state /// public TrackingState PreviousState { get; private set; } /// /// Initializes a new instance of the TrackedObject class. /// /// The track id. /// The detected object. /// The number of consecutive frames detected until it is considered to be tracked. /// The number of consecutive frames lost until the object will be deleted. public TrackedObject(int id, T detectedObject, int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted) { ID = id; this.numFramesDetectedUntilTracked = numFramesDetectedUntilTracked; this.numFramesLostUntilDeleted = numFramesLostUntilDeleted; wasTrackedBefore = false; CurrentObject = detectedObject; LastObject = detectedObject; CurrentState = TrackingState.Detected; PreviousState = TrackingState.Undefined; NumFramesInCurrentState = 1; } /// /// Adds the detectedObject to the tracking history and updates the current state. /// /// the best fitting trackableObject in the current frame public virtual void updateFrame(T detectedObject) { if (detectedObject != null) { detectedObject.setTracked(ID); LastObject = detectedObject; } TrackingState newState = getNewState(detectedObject); if (!wasTrackedBefore && newState == TrackingState.Tracked) wasTrackedBefore = true; PreviousState = CurrentState; CurrentState = newState; CurrentObject = detectedObject; if (PreviousState == newState) NumFramesInCurrentState++; else NumFramesInCurrentState = 1; } /// /// Calculates the new tracking state given the new trackableObject. /// /// the best fitting trackableObject in the current frame /// the new TrackingState private TrackingState getNewState(T detectedObject) { TrackingState newState = TrackingState.Undefined; if (detectedObject != null) { switch (CurrentState) { case TrackingState.Lost: if (wasTrackedBefore) newState = TrackingState.Tracked; else newState = TrackingState.Detected; break; case TrackingState.Tracked: newState = TrackingState.Tracked; break; case TrackingState.Detected: if (NumFramesInCurrentState >= numFramesDetectedUntilTracked) newState = TrackingState.Tracked; else newState = TrackingState.Detected; break; } } else if (CurrentState == TrackingState.Lost && NumFramesInCurrentState >= numFramesLostUntilDeleted) newState = TrackingState.Deleted; else newState = TrackingState.Lost; return newState; } } }