|
@@ -9,20 +9,128 @@ using bbiwarg.Graphics;
|
|
|
|
|
|
namespace bbiwarg.Recognition.FingerRecognition
|
|
namespace bbiwarg.Recognition.FingerRecognition
|
|
{
|
|
{
|
|
|
|
+ struct FingerSimilarity
|
|
|
|
+ {
|
|
|
|
+ public float similarity;
|
|
|
|
+ public FingerHistory fingerHistory;
|
|
|
|
+ public Finger fingerDetected;
|
|
|
|
+ }
|
|
|
|
+
|
|
class FingerTracker
|
|
class FingerTracker
|
|
{
|
|
{
|
|
- public List<TrackedFinger> TrackedFingers { get; private set; }
|
|
|
|
|
|
+ public List<FingerHistory> FingerHistories { get; private set; }
|
|
|
|
+ public List<Finger> Fingers { get; private set; }
|
|
|
|
+ private List<FingerSimilarity> similarities;
|
|
|
|
|
|
public FingerTracker()
|
|
public FingerTracker()
|
|
{
|
|
{
|
|
- TrackedFingers = new List<TrackedFinger>();
|
|
|
|
|
|
+ FingerHistories = new List<FingerHistory>();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void updateTrackedFingers(List<Finger> detectedFingers)
|
|
|
|
+ {
|
|
|
|
+ if (FingerHistories.Count == 0)
|
|
|
|
+ {
|
|
|
|
+ foreach (Finger finger in detectedFingers)
|
|
|
|
+ FingerHistories.Add(new FingerHistory(finger));
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ updateHistories(detectedFingers);
|
|
|
|
+ removeLongLostFingers();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void updateHistories(List<Finger> detectedFingers)
|
|
|
|
+ {
|
|
|
|
+ Fingers = new List<Finger>();
|
|
|
|
+
|
|
|
|
+ List<FingerHistory> unasignedFingerHistories = new List<FingerHistory>();
|
|
|
|
+ foreach (FingerHistory fh in FingerHistories)
|
|
|
|
+ unasignedFingerHistories.Add(fh);
|
|
|
|
+
|
|
|
|
+ List<Finger> unasignedDetectedFingers = new List<Finger>();
|
|
|
|
+ foreach (Finger f in detectedFingers)
|
|
|
|
+ unasignedDetectedFingers.Add(f);
|
|
|
|
+
|
|
|
|
+ createSimilarities(detectedFingers);
|
|
|
|
+
|
|
|
|
+ while (similarities.Count > 0)
|
|
|
|
+ {
|
|
|
|
+ FingerSimilarity maxSimilarity = similarities[0];
|
|
|
|
+ FingerHistory fingerHistory = maxSimilarity.fingerHistory;
|
|
|
|
+ Finger fingerDetected = maxSimilarity.fingerDetected;
|
|
|
|
+ fingerHistory.addFinger(fingerDetected);
|
|
|
|
+
|
|
|
|
+ Fingers.Add(fingerDetected);
|
|
|
|
+ unasignedFingerHistories.Remove(fingerHistory);
|
|
|
|
+ unasignedDetectedFingers.Remove(fingerDetected);
|
|
|
|
+ removeConcurringFingerSimilarities(maxSimilarity);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //add new fingerHistory for each new unmatched finger
|
|
|
|
+ foreach (Finger f in unasignedDetectedFingers)
|
|
|
|
+ {
|
|
|
|
+ FingerHistories.Add(new FingerHistory(f));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //add null finger to TrackedFingers that haven't found a match in this frame (status tracked->lost)
|
|
|
|
+ foreach (FingerHistory fh in unasignedFingerHistories)
|
|
|
|
+ {
|
|
|
|
+ fh.addFinger(null);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void createSimilarities(List<Finger> detectedFingers)
|
|
|
|
+ {
|
|
|
|
+ similarities = new List<FingerSimilarity>();
|
|
|
|
+
|
|
|
|
+ foreach (FingerHistory fh in FingerHistories)
|
|
|
|
+ {
|
|
|
|
+ foreach (Finger fingerDetected in detectedFingers)
|
|
|
|
+ {
|
|
|
|
+ float similarity = fingerDetected.getSimilarity(fh.LastFinger);
|
|
|
|
+ if (similarity > Constants.FingerMinSimilarityForTracking)
|
|
|
|
+ {
|
|
|
|
+ FingerSimilarity fs = new FingerSimilarity();
|
|
|
|
+ fs.similarity = similarity;
|
|
|
|
+ fs.fingerHistory = fh;
|
|
|
|
+ fs.fingerDetected = fingerDetected;
|
|
|
|
+ similarities.Add(fs);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ similarities.Sort((fs1, fs2) => fs1.similarity.CompareTo(fs2.similarity));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void removeConcurringFingerSimilarities(FingerSimilarity removeSimilarity)
|
|
|
|
+ {
|
|
|
|
+ for (int i = similarities.Count - 1; i >= 0; i--)
|
|
|
|
+ {
|
|
|
|
+ FingerSimilarity currentSimilarity = similarities[i];
|
|
|
|
+ if (currentSimilarity.fingerHistory == removeSimilarity.fingerHistory || currentSimilarity.fingerDetected == removeSimilarity.fingerDetected)
|
|
|
|
+ similarities.RemoveAt(i);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- public void updateTrackedFingers(List<Finger> detectedFingers) {
|
|
|
|
- Dictionary<TrackedFinger, Finger> assignments = new Dictionary<TrackedFinger, Finger>();
|
|
|
|
|
|
+ private void removeFingerDetectedFromSimilarities(Finger removeFinger)
|
|
|
|
+ {
|
|
|
|
+ for (int i = similarities.Count - 1; i >= 0; i--)
|
|
|
|
+ {
|
|
|
|
+ if (similarities[i].fingerDetected == removeFinger)
|
|
|
|
+ similarities.RemoveAt(i);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- foreach (TrackedFinger tf in TrackedFingers) {
|
|
|
|
- Finger bestFit = tf.findBestFit()
|
|
|
|
|
|
+ private void removeLongLostFingers()
|
|
|
|
+ {
|
|
|
|
+ for (int i = FingerHistories.Count - 1; i >= 0; i--)
|
|
|
|
+ {
|
|
|
|
+ FingerHistory tf = FingerHistories[i];
|
|
|
|
+ if (tf.CurrentState == TrackingState.Lost && tf.getNumFramesInCurrentState() >= Constants.FingerNumFramesUntilLost)
|
|
|
|
+ FingerHistories.RemoveAt(i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|