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 several TrackableObjects in different frames that have a high similarity 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 whether 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;
detectedObject.setTracked(ID);
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;
}
}
}