Преглед изворни кода

-rewritten trackers (added TrackedObject, similarities now use predicted positions, etc.)

Alexander Hendrich пре 11 година
родитељ
комит
ff25f8a265

+ 5 - 4
bbiwarg/Constants.cs

@@ -65,9 +65,9 @@ namespace bbiwarg
         public static readonly int FingerNumFramesDetectedUntilTracked = 5;
         public static readonly int FingerNumFramesLostUntilDeleted = 10;
         public static readonly float FingerMinSimilarityForTracking = 0.7f;
-        //public static readonly float FingerSimilarityMaxAngle = (float)(45 * Math.PI / 180); // 45°
-        //public static readonly float FingerSimilarityMaxParallelDistance = 100;
-        //public static readonly float FingerSimilarityMaxVerticalDistance = 20;
+        public static readonly float FingermXX = 0.0005f;
+        public static readonly float FingermXY = 0.0005f;
+        public static readonly float FingermYY = 0.0005f;
 
         // hand detection
         public static readonly float HandMaxSize = 0.7f;
@@ -90,7 +90,7 @@ namespace bbiwarg
         public static readonly float PalmMaxPrecentageQuadForegroundReset = 0.5f;
 
         //palm Grid
-        public static readonly int PalmGridNumRows = 3;
+        public static readonly int PalmGridNumRows = 4;
         public static readonly int PalmGridNumColumns = 3;
 
         // touch detection
@@ -127,6 +127,7 @@ namespace bbiwarg
         public static readonly Color FingerTipColor = Color.Blue;
         public static readonly Color FingerContourColor = Color.Red;
         public static readonly Color FingerIDColor = Color.White;
+        public static readonly Color FingerPointsPredictionColor = Color.Yellow;
 
         public static readonly Color TouchEventDetectedColor = ColorDetected;
         public static readonly Color TouchEventTrackedColor = ColorTracked;

+ 14 - 15
bbiwarg/Graphics/TouchEventVisualizer.cs

@@ -32,27 +32,32 @@ namespace bbiwarg.Graphics
             this.timer.Start();
         }
 
-        public void touchDown(object sender, PalmTouchEventArgs ptea)
+        public void reset()
+        {
+            currentPositions.Clear();
+        }
+
+        public void touchDown(object sender, TouchEventArgs tea)
         {
             List<Vector2D> posList = new List<Vector2D>();
-            posList.Add(ptea.Position);
-            currentPositions.Add(ptea.TrackID, posList);
+            posList.Add(tea.RelativePosition);
+            currentPositions.Add(tea.TrackID, posList);
         }
 
 
-        public void touchMove(object sender, PalmTouchEventArgs ptea)
+        public void touchMove(object sender, TouchEventArgs tea)
         {
-            currentPositions[ptea.TrackID].Add(ptea.Position);
+            currentPositions[tea.TrackID].Add(tea.RelativePosition);
         }
 
-        public void touchUp(object sender, PalmTouchEventArgs ptea)
+        public void touchUp(object sender, TouchEventArgs tea)
         {
-            currentPositions[ptea.TrackID].Add(ptea.Position);
+            currentPositions[tea.TrackID].Add(tea.RelativePosition);
 
-            List<Vector2D> posList = currentPositions[ptea.TrackID];
+            List<Vector2D> posList = currentPositions[tea.TrackID];
             oldPositions.Add(timer.ElapsedMilliseconds, posList);
 
-            currentPositions.Remove(ptea.TrackID);
+            currentPositions.Remove(tea.TrackID);
         }
 
         public void updateImage()
@@ -113,11 +118,5 @@ namespace bbiwarg.Graphics
             Vector2D lastPos = positions[numPositions - 1].scale(maxPixel);
             OutputImage.fillCircle(lastPos.IntX, lastPos.IntY, 3, pointColorFaded);
         }
-
-        public void reset()
-        {
-            OutputImage = new OutputImage(width, height);
-            currentPositions.Clear();
-        }
     }
 }

+ 17 - 9
bbiwarg/InputHandler.cs

@@ -10,6 +10,7 @@ using bbiwarg.Recognition.FingerRecognition;
 using bbiwarg.Recognition.HandRecognition;
 using bbiwarg.Recognition.PalmRecognition;
 using bbiwarg.Recognition.TouchRecognition;
+using bbiwarg.Recognition.Tracking;
 using bbiwarg.Server;
 using bbiwarg.Graphics;
 using bbiwarg.Utility;
@@ -66,9 +67,9 @@ namespace bbiwarg
             {
                 touchEventVisualizer = new TouchEventVisualizer(imageWidth, imageHeight);
                 //register touchEventVisualizer to touchTracker
-                touchTracker.PalmTouchDown += touchEventVisualizer.touchDown;
-                touchTracker.PalmTouchMove += touchEventVisualizer.touchMove;
-                touchTracker.PalmTouchUp += touchEventVisualizer.touchUp;
+                touchTracker.TouchDown += touchEventVisualizer.touchDown;
+                touchTracker.TouchMove += touchEventVisualizer.touchMove;
+                touchTracker.TouchUp += touchEventVisualizer.touchUp;
             }
 
             if (Constants.TuioEnabled)
@@ -76,9 +77,9 @@ namespace bbiwarg
                 tuioCommunicator = new TuioCommunicator(Constants.TuioIP, Constants.TuioPort);
 
                 //register tuiCommunicator to touchTracker
-                touchTracker.PalmTouchDown += tuioCommunicator.touchDown;
-                touchTracker.PalmTouchMove += tuioCommunicator.touchMove;
-                touchTracker.PalmTouchUp += tuioCommunicator.touchUp;
+                touchTracker.TouchDown += tuioCommunicator.touchDown;
+                touchTracker.TouchMove += tuioCommunicator.touchMove;
+                touchTracker.TouchUp += tuioCommunicator.touchUp;
             }
         }
 
@@ -235,9 +236,16 @@ namespace bbiwarg
             OutputImages[0].drawImage((depthImage.MaxDepth - depthImage.MinDepth) - depthImage.Image, Constants.DepthImageColor);
             foreach (Finger f in fingerTracker.Fingers)
             {
-                OutputImages[0].fillCircle(f.TipPoint.IntX, f.TipPoint.IntY, 3, Constants.FingerTipColor);
-                if (f.TouchEvent != null)
-                    OutputImages[0].fillCircle(f.TouchEvent.Position.IntX, f.TouchEvent.Position.IntY, 5, Constants.TouchEventDetectedColor);
+                OutputImages[0].fillCircle(f.TipPoint.IntX, f.TipPoint.IntY, 4, Constants.FingerTipColor);
+            }
+
+            foreach (TrackedFinger tf in fingerTracker.TrackedObjects)
+            {
+                if (tf.CurrentState == TrackingState.Tracked)
+                {
+                    OutputImages[0].fillCircle(tf.TipPointPrediction.IntX, tf.TipPointPrediction.IntY, 3, Constants.FingerPointsPredictionColor);
+                    OutputImages[0].fillCircle(tf.HandPointPrediction.IntX, tf.HandPointPrediction.IntY, 3, Constants.FingerPointsPredictionColor);
+                }
             }
 
             //image1

+ 0 - 34
bbiwarg/Recognition/FingerRecognition/Finger.cs

@@ -34,40 +34,6 @@ namespace bbiwarg.Recognition.FingerRecognition
             SliceTrail = sliceTrail;
         }
 
-        public override float getSimilarity(TrackableObject compareObject)
-        {
-            Finger compareFinger = (Finger)compareObject;
-            LineSegment2D compareLineSegment = compareFinger.LineSegment;
-            Line2D compareLine = compareLineSegment.Line;
-
-            //tip position
-            float tipPointDistance = TipPoint.getDistanceTo(compareFinger.TipPoint);
-            float tipPointSimilarity = Math.Max(0, 1 - tipPointDistance / Constants.ImageDiagonalLength);
-
-            //hand position
-            float handPointDistance = HandPoint.getDistanceTo(compareFinger.HandPoint);
-            float handPointSimilarity = Math.Max(0, 1 - handPointDistance / Constants.ImageDiagonalLength);
-            /*
-            //check angle
-            float angle = LineSegment.Line.getAngleBetween(compareLine);
-            float angleSimilarity = Math.Max(1 - angle / Constants.FingerSimilarityMaxAngle, 0);
-
-            //check parallel distance
-            float parallelDistance = LineSegment.getParallelDistanceTo(compareLineSegment);
-            float parallelDistanceSimilarity = Math.Max(1 - parallelDistance / Constants.FingerSimilarityMaxParallelDistance, 0);
-
-            //check vertical distance
-            float verticalDistance = LineSegment.getVerticalDistanceTo(compareLineSegment);
-            float verticalDistanceSimilarity = Math.Max(1 - verticalDistance / Constants.FingerSimilarityMaxVerticalDistance, 0);
-            */
-            float similarity = tipPointSimilarity * handPointSimilarity;
-            //float similarity = tipPointSimilarity * handPointSimilarity * angleSimilarity * parallelDistanceSimilarity * verticalDistanceSimilarity;
-            //float similarity = (tipPointSimilarity + handPointSimilarity + angleSimilarity + parallelDistanceSimilarity + verticalDistanceSimilarity)/5;
-            //float similarity = (angleSimilarity + parallelDistanceSimilarity + verticalDistanceSimilarity) / 3;
-
-            return similarity;
-        }
-
         public void setHand(Hand hand)
         {
             Hand = hand;

+ 7 - 35
bbiwarg/Recognition/FingerRecognition/FingerTracker.cs

@@ -8,48 +8,20 @@ using bbiwarg.Utility;
 
 namespace bbiwarg.Recognition.FingerRecognition
 {
-    class FingerTracker : Tracker<Finger>
-    {
-        public List<Finger> Fingers { get { return TrackedObjects; } }
-
-        public FingerTracker()
-            : base(Constants.FingerNumFramesDetectedUntilTracked, Constants.FingerNumFramesLostUntilDeleted, Constants.FingerMinSimilarityForTracking)
-        {
-        }
-
-        protected override void onDetect(object sender, EventArgs e)
-        {
-            TrackableObjectHistory<Finger> history = (TrackableObjectHistory<Finger>)sender;
-            if (history.NumFramesInCurrentState == 1)
-                Logger.log("Finger #" + history.ID.ToString() + " detected", LogSubject.FingerTracker);
-        }
 
-        protected override void onTrack(object sender, EventArgs e)
-        {
-            TrackableObjectHistory<Finger> history = (TrackableObjectHistory<Finger>)sender;
-            if (history.NumFramesInCurrentState == 1)
-                Logger.log("Finger #" + history.ID.ToString() + " tracked", LogSubject.FingerTracker);
-        }
+    class FingerTracker : Tracker<Finger, TrackedFinger>
+    {
 
-        protected override void onRetrack(object sender, EventArgs e)
-        {
-            TrackableObjectHistory<Finger> history = (TrackableObjectHistory<Finger>)sender;
-            if (history.NumFramesInCurrentState == 1)
-                Logger.log("Finger #" + history.ID.ToString() + " retracked", LogSubject.FingerTracker);
-        }
+        public List<Finger> Fingers { get { return getCurrentObjectsWithState(TrackingState.Tracked); } }
 
-        protected override void onLoose(object sender, EventArgs e)
+        public FingerTracker()
+            : base(Constants.FingerMinSimilarityForTracking)
         {
-            TrackableObjectHistory<Finger> history = (TrackableObjectHistory<Finger>)sender;
-            if (history.NumFramesInCurrentState == 1)
-                Logger.log("Finger #" + history.ID.ToString() + " lost", LogSubject.FingerTracker);
         }
 
-        protected override void onDelete(object sender, EventArgs e)
+        protected override TrackedFinger createTrackedObject(Finger detectedObject)
         {
-            TrackableObjectHistory<Finger> history = (TrackableObjectHistory<Finger>)sender;
-            if (history.NumFramesInCurrentState == 1)
-                Logger.log("Finger #" + history.ID.ToString() + " deleted", LogSubject.FingerTracker);
+            return new TrackedFinger(idPool.getNextUnusedID(), detectedObject, Constants.FingerNumFramesDetectedUntilTracked, Constants.FingerNumFramesLostUntilDeleted);
         }
     }
 }

+ 63 - 0
bbiwarg/Recognition/FingerRecognition/TrackedFinger.cs

@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using bbiwarg.Recognition.Tracking;
+using bbiwarg.Utility;
+
+namespace bbiwarg.Recognition.FingerRecognition
+{
+    class TrackedFinger : TrackedObject<Finger>
+    {
+        private Kalman2DPositionFilter tipPointKalman;
+        private Kalman2DPositionFilter handPointKalman;
+
+        public Vector2D TipPointPrediction { get { return tipPointKalman.getPrediction(); } }
+        public Vector2D HandPointPrediction { get { return handPointKalman.getPrediction(); } }
+
+        public TrackedFinger(int id, Finger detectedFinger, int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted)
+            : base(id, detectedFinger, numFramesDetectedUntilTracked, numFramesLostUntilDeleted)
+        {
+            tipPointKalman = new Kalman2DPositionFilter(Constants.FingermXX, Constants.FingermXY, Constants.FingermYY);
+            tipPointKalman.setInitialPosition(detectedFinger.TipPoint);
+            handPointKalman = new Kalman2DPositionFilter(Constants.FingermXX, Constants.FingermXY, Constants.FingermYY);
+            handPointKalman.setInitialPosition(detectedFinger.HandPoint);
+
+            logStateChange();
+        }
+
+        public override void updateFrame(Finger detectedObject)
+        {
+            base.updateFrame(detectedObject);
+
+            if (NumFramesInCurrentState == 1)
+                logStateChange();
+
+            if (detectedObject != null)
+            {
+                tipPointKalman.getCorrectedPosition(detectedObject.TipPoint);
+                handPointKalman.getCorrectedPosition(detectedObject.HandPoint);
+            }
+        }
+
+        public override float getSimilarity(Finger detectedFinger)
+        {
+            //tip position
+            float tipPointDistance = detectedFinger.TipPoint.getDistanceTo(TipPointPrediction);
+            float tipPointSimilarity = Math.Max(0, 1 - tipPointDistance / Constants.ImageDiagonalLength);
+
+            //hand position
+            float handPointDistance = detectedFinger.HandPoint.getDistanceTo(HandPointPrediction);
+            float handPointSimilarity = Math.Max(0, 1 - handPointDistance / Constants.ImageDiagonalLength);
+
+            return tipPointSimilarity * handPointSimilarity;
+        }
+
+        private void logStateChange()
+        {
+            String stateAsString = CurrentState.ToString().ToLower();
+            Logger.log(String.Format("Finger #{0} {1}", this.ID, stateAsString), LogSubject.FingerTracker);
+        }
+    }
+}

+ 0 - 24
bbiwarg/Recognition/TouchRecognition/PalmTouchEvent.cs

@@ -1,24 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using bbiwarg.Utility;
-using bbiwarg.Recognition.FingerRecognition;
-using bbiwarg.Recognition.PalmRecognition;
-using Emgu.CV;
-using Emgu.CV.Structure;
-
-namespace bbiwarg.Recognition.TouchRecognition
-{
-    class PalmTouchEvent : TouchEvent
-    {
-        public Vector2D RelativePalmPosition { get; private set; }
-
-        public PalmTouchEvent(Vector2D absolutePosition, Image<Gray, byte> touchMask, Finger finger, Quadrangle palmQuad)
-            : base(absolutePosition, touchMask, finger)
-        {
-            RelativePalmPosition = palmQuad.getRelativePosition(absolutePosition);
-        }
-    }
-}

+ 16 - 10
bbiwarg/Recognition/TouchRecognition/TouchDetector.cs

@@ -18,14 +18,22 @@ namespace bbiwarg.Recognition.TouchRecognition
     {
         private DepthImage depthImage;
         private List<Finger> fingers;
+        private Quadrangle palmQuad;
+
         public List<TouchEvent> TouchEvents { get; private set; }
 
         public TouchDetector(DepthImage depthImage, List<Finger> fingers, Quadrangle palmQuad)
         {
             this.depthImage = depthImage;
             this.fingers = fingers;
-            this.TouchEvents = new List<TouchEvent>();
+            this.palmQuad = palmQuad;
+            TouchEvents = new List<TouchEvent>();
+
+            if (palmQuad != null)
+                detectTouch();
+        }
 
+        private void detectTouch() {
             foreach (Finger finger in fingers)
             {
                 Vector2D tipPoint = finger.TipPoint;
@@ -34,22 +42,20 @@ namespace bbiwarg.Recognition.TouchRecognition
                 Vector2D tipPointInside = (tipPoint + Constants.TouchEventTipInsideFactor * directionInv).moveInBound(Vector2D.Zero, depthImage.BottomRight, direction);
                 Vector2D tipPointOutside = (tipPoint + Constants.TouchEventTipOutsideFactor * direction).moveInBound(Vector2D.Zero, depthImage.BottomRight, directionInv);
 
-                Image<Gray, byte> touchMask = getTouchMask(tipPointInside);
+                if(palmQuad.isInside(tipPointOutside)) {
 
-                int touchPixels = touchMask.CountNonzero()[0];
-                int numPixels = touchMask.Width * touchMask.Height;
-                float touchValue = touchPixels / (float)numPixels;
+                    Image<Gray, byte> touchMask = getTouchMask(tipPointInside);
 
-                if (touchValue > Constants.TouchEventMinTouchValue)
-                {
+                    int touchPixels = touchMask.CountNonzero()[0];
+                    int numPixels = touchMask.Width * touchMask.Height;
+                    float touchValue = touchPixels / (float)numPixels;
 
-                    if (palmQuad != null && palmQuad.isInside(tipPointOutside))
+                    if (touchValue > Constants.TouchEventMinTouchValue)
                     {
-                        TouchEvent touchEvent = new PalmTouchEvent(tipPointOutside, touchMask, finger, palmQuad);
+                        TouchEvent touchEvent = new TouchEvent(tipPointOutside, touchMask, finger, palmQuad);
                         TouchEvents.Add(touchEvent);
                         finger.setTouchEvent(touchEvent);
                     }
-
                 }
             }
         }

+ 7 - 18
bbiwarg/Recognition/TouchRecognition/TouchEvent.cs

@@ -14,14 +14,19 @@ namespace bbiwarg.Recognition.TouchRecognition
     class TouchEvent : TrackableObject
     {
         public Vector2D Position { get; private set; }
+        public Vector2D RelativePalmPosition { get; private set; }
         public Image<Gray, byte> TouchMask { get; private set; }
         public Finger Finger { get; private set; }
+        public Quadrangle PalmQuad { get; private set; }
 
-        public TouchEvent(Vector2D position, Image<Gray, byte> touchMask, Finger finger)
+
+        public TouchEvent(Vector2D absolutePosition, Image<Gray, byte> touchMask, Finger finger, Quadrangle palmQuad)
         {
-            Position = position;
+            Position = absolutePosition;
+            RelativePalmPosition = palmQuad.getRelativePosition(absolutePosition);
             TouchMask = touchMask;
             Finger = finger;
+            PalmQuad = palmQuad;
         }
 
         public float getTouchValue()
@@ -31,21 +36,5 @@ namespace bbiwarg.Recognition.TouchRecognition
             float touchValue = touchPixels / (float)numPixels;
             return touchValue;
         }
-
-        public override float getSimilarity(TrackableObject compareObject)
-        {
-            TouchEvent compareTouchEvent = (TouchEvent)compareObject;
-
-            //finger similarity
-            float fingerSimilarity = (Finger.TrackID == compareTouchEvent.Finger.TrackID) ? 1 : 0;
-
-            //position similarity
-            float distance = Position.getDistanceTo(compareTouchEvent.Position);
-            float distanceSimilarity = Math.Max(0, 1 - distance / Constants.ImageDiagonalLength);
-
-            float similarity = fingerSimilarity * distanceSimilarity;
-
-            return similarity;
-        }
     }
 }

+ 31 - 7
bbiwarg/Recognition/TouchRecognition/TouchTracker.cs

@@ -11,6 +11,30 @@ using bbiwarg.Utility;
 
 namespace bbiwarg.Recognition.TouchRecognition
 {
+    class TouchTracker : Tracker<TouchEvent, TrackedTouchEvent>
+    {
+        public List<TouchEvent> TouchEvents { get { return getCurrentObjectsWithState(TrackingState.Tracked); } }
+
+        public event TouchEventHandler TouchDown;
+        public event TouchEventHandler TouchMove;
+        public event TouchEventHandler TouchUp;
+
+        public TouchTracker()
+            : base(Constants.TouchEventMinSimilarityForTracking)
+        {
+        }
+
+        protected override TrackedTouchEvent createTrackedObject(TouchEvent detectedObject)
+        {
+            TrackedTouchEvent tte = new TrackedTouchEvent(idPool.getNextUnusedID(), detectedObject, Constants.TouchEventNumFramesDetectedUntilTracked, Constants.TouchEventNumFramesLostUntilDeleted);
+            tte.TouchDown += TouchDown;
+            tte.TouchMove += TouchMove;
+            tte.TouchUp += TouchUp;
+            return tte;
+        }
+    }
+
+    /*
     public class PalmTouchEventArgs : EventArgs
     {
         public int TrackID { get; private set; }
@@ -25,7 +49,7 @@ namespace bbiwarg.Recognition.TouchRecognition
 
     public delegate void PalmTouchEventHandler(object sender, PalmTouchEventArgs e);
 
-    class TouchTracker : Tracker<TouchEvent>
+    class TouchTracker : OldTracker<TouchEvent>
     {
         public List<TouchEvent> TouchEvents { get { return TrackedObjects; } }
         public Dictionary<int, Kalman2DPositionFilter> kalmanFilters;
@@ -55,14 +79,14 @@ namespace bbiwarg.Recognition.TouchRecognition
 
         protected override void onDetect(object sender, EventArgs e)
         {
-            TrackableObjectHistory<TouchEvent> history = (TrackableObjectHistory<TouchEvent>)sender;
+            OldTrackableObjectHistory<TouchEvent> history = (OldTrackableObjectHistory<TouchEvent>)sender;
             if (history.NumFramesInCurrentState == 1)
                 Logger.log("TouchEvent #" + history.ID.ToString() + " detected", LogSubject.TouchTracker);
         }
 
         protected override void onTrack(object sender, EventArgs e)
         {
-            TrackableObjectHistory<TouchEvent> history = (TrackableObjectHistory<TouchEvent>)sender;
+            OldTrackableObjectHistory<TouchEvent> history = (OldTrackableObjectHistory<TouchEvent>)sender;
             if (history.NumFramesInCurrentState == 1)
                 Logger.log("TouchEvent #" + history.ID.ToString() + " tracked", LogSubject.TouchTracker);
 
@@ -78,7 +102,7 @@ namespace bbiwarg.Recognition.TouchRecognition
 
         protected override void onRetrack(object sender, EventArgs e)
         {
-            TrackableObjectHistory<TouchEvent> history = (TrackableObjectHistory<TouchEvent>)sender;
+            OldTrackableObjectHistory<TouchEvent> history = (OldTrackableObjectHistory<TouchEvent>)sender;
             if (history.NumFramesInCurrentState == 1)
                 Logger.log("TouchEvent #" + history.ID.ToString() + " retracked", LogSubject.TouchTracker);
 
@@ -92,14 +116,14 @@ namespace bbiwarg.Recognition.TouchRecognition
 
         protected override void onLoose(object sender, EventArgs e)
         {
-            TrackableObjectHistory<TouchEvent> history = (TrackableObjectHistory<TouchEvent>)sender;
+            OldTrackableObjectHistory<TouchEvent> history = (OldTrackableObjectHistory<TouchEvent>)sender;
             if (history.NumFramesInCurrentState == 1)
                 Logger.log("TouchEvent #" + history.ID.ToString() + " lost", LogSubject.TouchTracker);
         }
 
         protected override void onDelete(object sender, EventArgs e)
         {
-            TrackableObjectHistory<TouchEvent> history = (TrackableObjectHistory<TouchEvent>)sender;
+            OldTrackableObjectHistory<TouchEvent> history = (OldTrackableObjectHistory<TouchEvent>)sender;
             if (history.NumFramesInCurrentState == 1)
                 Logger.log("TouchEvent #" + history.ID.ToString() + " deleted", LogSubject.TouchTracker);
 
@@ -139,5 +163,5 @@ namespace bbiwarg.Recognition.TouchRecognition
                 Logger.log("TouchEvent #" + id.ToString() + " touchUp at (" + relPos.X + ", " + relPos.Y + ")", LogSubject.TouchEvents);
             }
         }
-    }
+    }*/
 }

+ 130 - 0
bbiwarg/Recognition/TouchRecognition/TrackedTouchEvent.cs

@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using bbiwarg.Recognition.Tracking;
+using bbiwarg.Utility;
+
+namespace bbiwarg.Recognition.TouchRecognition
+{
+    public delegate void TouchEventHandler(object sender, TouchEventArgs e);
+    public class TouchEventArgs : EventArgs
+    {
+        public int TrackID { get; private set; }
+        public Vector2D AbsolutePosition { get; private set; }
+        public Vector2D RelativePosition { get; private set; }
+
+        public TouchEventArgs(int trackID, Vector2D absolutePosition, Vector2D relativePosition)
+        {
+            TrackID = trackID;
+            AbsolutePosition = absolutePosition;
+            RelativePosition = relativePosition;
+        }
+    }
+
+    class TrackedTouchEvent : TrackedObject<TouchEvent>
+    {
+        private Kalman2DPositionFilter absolutePositionKalman;
+        private Kalman2DPositionFilter relativePositionKalman;
+        private int fingerID;
+        private bool isTouchActive;
+
+        public Vector2D AbsolutePositionPrediction { get { return absolutePositionKalman.getPrediction(); } }
+        public Vector2D RelativePositionPrediction { get { return relativePositionKalman.getPrediction(); } }
+
+        public event TouchEventHandler TouchDown;
+        public event TouchEventHandler TouchMove;
+        public event TouchEventHandler TouchUp;
+
+        public TrackedTouchEvent(int id, TouchEvent detectedTouchEvent, int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted)
+            : base(id, detectedTouchEvent, numFramesDetectedUntilTracked, numFramesLostUntilDeleted)
+        {
+            absolutePositionKalman = new Kalman2DPositionFilter(Constants.TouchmXX, Constants.TouchmXY, Constants.TouchmYY);
+            absolutePositionKalman.setInitialPosition(detectedTouchEvent.Position);
+
+            relativePositionKalman = new Kalman2DPositionFilter(Constants.TouchmXX, Constants.TouchmXY, Constants.TouchmYY);
+            relativePositionKalman.setInitialPosition(detectedTouchEvent.RelativePalmPosition);
+
+            fingerID = detectedTouchEvent.Finger.TrackID;
+            isTouchActive = false;
+
+            logStateChange();
+        }
+
+        public override void updateFrame(TouchEvent detectedTouchEvent)
+        {
+            base.updateFrame(detectedTouchEvent);
+
+            if (NumFramesInCurrentState == 1)
+                logStateChange();
+
+            if (detectedTouchEvent != null)
+            {
+                Vector2D correctedAbsolutePosition = absolutePositionKalman.getCorrectedPosition(detectedTouchEvent.Position);
+                Vector2D correctedRelativePosition = relativePositionKalman.getCorrectedPosition(detectedTouchEvent.RelativePalmPosition);
+
+                if (CurrentState == TrackingState.Tracked)
+                {
+                    if (!isTouchActive)
+                        TriggerTouchDown(new TouchEventArgs(ID, correctedAbsolutePosition, correctedRelativePosition));
+                    else
+                        TriggerTouchMove(new TouchEventArgs(ID, correctedAbsolutePosition, correctedRelativePosition));
+                }
+            }
+            else if (isTouchActive && CurrentState == TrackingState.Deleted)
+                TriggerTouchUp(new TouchEventArgs(ID, AbsolutePositionPrediction, RelativePositionPrediction));
+
+        }
+
+        public override float getSimilarity(TouchEvent detectedTouchEvent)
+        {
+            //finger similarity
+            float fingerSimilarity = (fingerID == detectedTouchEvent.Finger.TrackID) ? 1 : 0;
+
+            //position similarity
+            float distance = detectedTouchEvent.Position.getDistanceTo(AbsolutePositionPrediction);
+            float distanceSimilarity = Math.Max(0, 1 - distance / Constants.ImageDiagonalLength);
+
+            float similarity = fingerSimilarity * distanceSimilarity;
+
+            return similarity;
+        }
+
+        private void logStateChange()
+        {
+            String stateAsString = CurrentState.ToString().ToLower();
+            Logger.log(String.Format("TouchEvent #{0} {1}", this.ID, stateAsString), LogSubject.TouchTracker);
+        }
+
+        private void TriggerTouchDown(TouchEventArgs e)
+        {
+            if (TouchDown != null)
+            {
+                isTouchActive = true;
+                TouchDown(this, e);
+                Logger.log(String.Format("TouchEvent #{0} TouchDown at {1}", this.ID, e.RelativePosition), LogSubject.TouchEvents);
+            }
+        }
+
+        private void TriggerTouchMove(TouchEventArgs e)
+        {
+            if (TouchMove != null)
+            {
+                TouchMove(this, e);
+                Logger.log(String.Format("TouchEvent #{0} TouchMove at {1}", this.ID, e.RelativePosition), LogSubject.TouchEvents);
+            }
+        }
+
+        private void TriggerTouchUp(TouchEventArgs e)
+        {
+            if (TouchUp != null)
+            {
+                isTouchActive = false;
+                TouchUp(this, e);
+                Logger.log(String.Format("TouchEvent #{0} TouchUp at {1}", this.ID, e.RelativePosition), LogSubject.TouchEvents);
+            }
+        }
+
+    }
+}

+ 23 - 0
bbiwarg/Recognition/Tracking/Similarity.cs

@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace bbiwarg.Recognition.Tracking
+{
+    public class Similarity<T, TrackedT> 
+        where T :TrackableObject
+        where TrackedT : TrackedObject<T>
+    {
+        public TrackedT TrackedObject { get; private set; }
+        public T DetectedObject { get; private set; }
+        public float Value { get; private set; }
+
+        public Similarity(TrackedT trackedObject, T detectedObject, float value) {
+            TrackedObject = trackedObject;
+            DetectedObject = detectedObject;
+            Value = value;
+        }
+    }
+}

+ 0 - 22
bbiwarg/Recognition/Tracking/SimilarityContainer.cs

@@ -1,22 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace bbiwarg.Recognition.Tracking
-{
-    class SimilarityContainer<T> where T : TrackableObject
-    {
-        public float Similarity { get; private set; }
-        public TrackableObjectHistory<T> History { get; private set; }
-        public T DetectedObject { get; private set; }
-
-        public SimilarityContainer(TrackableObjectHistory<T> history, T detectedObject)
-        {
-            Similarity = detectedObject.getSimilarity(history.LastObject);
-            History = history;
-            DetectedObject = detectedObject;
-        }
-    }
-}

+ 31 - 0
bbiwarg/Recognition/Tracking/TrackIDPool.cs

@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace bbiwarg.Recognition.Tracking
+{
+    class TrackIDPool
+    {
+        private List<int> usedIDs;
+
+        public TrackIDPool() {
+            usedIDs = new List<int>();
+        }
+
+        public int getNextUnusedID()
+        {
+            int id = 1;
+            while (usedIDs.Contains(id))
+                id++;
+            usedIDs.Add(id);
+            return id;
+        }
+
+        public void setIDUnused(int id)
+        {
+            usedIDs.Remove(id);
+        }
+    }
+}

+ 2 - 10
bbiwarg/Recognition/Tracking/TrackableObject.cs

@@ -6,19 +6,11 @@ using System.Threading.Tasks;
 
 namespace bbiwarg.Recognition.Tracking
 {
-    abstract class TrackableObject
+    public class TrackableObject
     {
         public int TrackID { get; private set; }
 
-        public TrackableObject()
-        {
-            TrackID = 0;
-        }
-
-        abstract public float getSimilarity(TrackableObject compareObject);
-
-        public void setTrackID(int id)
-        {
+        public void setTracked(int id) {
             TrackID = id;
         }
     }

+ 0 - 144
bbiwarg/Recognition/Tracking/TrackableObjectHistory.cs

@@ -1,144 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using bbiwarg.Utility;
-
-namespace bbiwarg.Recognition.Tracking
-{
-    public delegate void TrackingStateChangedEventHandler(object sender, EventArgs e);
-
-    class TrackableObjectHistory<T> where T : TrackableObject
-    {
-        private static List<int> usedIDs = new List<int>();
-        public int ID { get; private set; }
-        public List<T> TrackedObjects { get; private set; }
-        public List<TrackingState> States { get; private set; }
-        public T LastObject { get; private set; }
-        public T CurrentObject { get { return TrackedObjects[TrackedObjects.Count - 1]; } }
-        public TrackingState CurrentState { get { return States[States.Count - 1]; } }
-        public int NumFramesInCurrentState { get; private set; }
-        private int numFramesDetectedUntilTracked;
-        private int numFramesLostUntilDeleted;
-        private bool wasTrackedBefore;
-
-        public event TrackingStateChangedEventHandler Detected;
-        public event TrackingStateChangedEventHandler Tracked;
-        public event TrackingStateChangedEventHandler Retracked;
-        public event TrackingStateChangedEventHandler Lost;
-        public event TrackingStateChangedEventHandler Deleted;
-
-        protected virtual void OnDetect(EventArgs e) { if (Detected != null) Detected(this, e); }
-        protected virtual void OnTrack(EventArgs e) { if (Tracked != null) Tracked(this, e); }
-        protected virtual void OnRetrack(EventArgs e) { if (Retracked != null) Retracked(this, e); }
-        protected virtual void OnLoose(EventArgs e) { if (Lost != null) Lost(this, e); }
-        protected virtual void OnDelete(EventArgs e) { if (Deleted != null) Deleted(this, e); }
-
-        public TrackableObjectHistory(int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted)
-        {
-            ID = getNextUnusedID();
-            TrackedObjects = new List<T>();
-            TrackedObjects.Add(null);
-            States = new List<TrackingState>();
-            States.Add(TrackingState.None);
-            NumFramesInCurrentState = 1;
-            this.numFramesDetectedUntilTracked = numFramesDetectedUntilTracked;
-            this.numFramesLostUntilDeleted = numFramesLostUntilDeleted;
-            this.wasTrackedBefore = false;
-        }
-
-        ~TrackableObjectHistory()
-        {
-            setIDUnused(ID);
-        }
-
-        public void addObjectToHistory(T detectedObject)
-        {
-            TrackingState previousState = CurrentState;
-            TrackingState newState = TrackingState.None;
-
-            //get newState
-            if (detectedObject != null)
-            {
-                if (previousState == TrackingState.None)
-                    newState = TrackingState.Detected;
-                else if (previousState == TrackingState.Lost)
-                {
-                    if (wasTrackedBefore)
-                        newState = TrackingState.Tracked;
-                    else
-                        newState = TrackingState.Detected;
-                }
-                else if (previousState == TrackingState.Tracked)
-                    newState = TrackingState.Tracked;
-                else if (previousState == TrackingState.Detected)
-                {
-                    if (NumFramesInCurrentState == numFramesDetectedUntilTracked)
-                        newState = TrackingState.Tracked;
-                    else
-                        newState = TrackingState.Detected;
-                }
-            }
-            else if (previousState == TrackingState.Lost && NumFramesInCurrentState == numFramesLostUntilDeleted)
-                newState = TrackingState.Delete;
-            else
-                newState = TrackingState.Lost;
-
-            //set trackedBefore
-            if (newState == TrackingState.Tracked)
-                wasTrackedBefore = true;
-
-            //update numFramesInCurrentState
-            if (newState == previousState)
-                NumFramesInCurrentState++;
-            else
-                NumFramesInCurrentState = 1;
-
-            //update lastObject
-            if (detectedObject != null)
-            {
-                LastObject = detectedObject;
-                detectedObject.setTrackID(ID);
-            }
-
-            //add current state+object
-            TrackedObjects.Add(detectedObject);
-            States.Add(newState);
-
-            //fire event
-            switch (newState)
-            {
-                case TrackingState.Detected:
-                    OnDetect(EventArgs.Empty);
-                    break;
-                case TrackingState.Tracked:
-                    if (previousState == TrackingState.Lost)
-                        OnRetrack(EventArgs.Empty);
-                    else
-                        OnTrack(EventArgs.Empty);
-                    break;
-                case TrackingState.Lost:
-                    OnLoose(EventArgs.Empty);
-                    break;
-                case TrackingState.Delete:
-                    OnDelete(EventArgs.Empty);
-                    break;
-            }
-        }
-
-        public static int getNextUnusedID()
-        {
-            int id = 1;
-            while (usedIDs.Contains(id))
-                id++;
-            usedIDs.Add(id);
-            return id;
-        }
-
-        public static void setIDUnused(int id)
-        {
-            usedIDs.Remove(id);
-        }
-    }
-}

+ 101 - 0
bbiwarg/Recognition/Tracking/TrackedObject.cs

@@ -0,0 +1,101 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace bbiwarg.Recognition.Tracking
+{
+    public enum TrackingState
+    {
+        Undefined = 0,
+        Detected = 1,
+        Tracked = 2,
+        Lost = 3,
+        Deleted = 4
+    }
+
+    public abstract class TrackedObject<T> where T : TrackableObject
+    {
+        private int numFramesDetectedUntilTracked;
+        private int numFramesLostUntilDeleted;
+        private bool wasTrackedBefore;
+
+        public int ID { get; private set; }
+        public List<T> DetectedObjects;
+        public T CurrentObject { get { return DetectedObjects[DetectedObjects.Count - 1]; } }
+        public List<TrackingState> States;
+        public TrackingState CurrentState { get { return States[States.Count - 1]; } }
+        public int NumFramesInCurrentState { get; private set; }
+
+        public TrackedObject(int id, T detectedObject, int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted)
+        {
+            ID = id;
+            this.numFramesDetectedUntilTracked = numFramesDetectedUntilTracked;
+            this.numFramesLostUntilDeleted = numFramesLostUntilDeleted;
+            wasTrackedBefore = false;
+            DetectedObjects = new List<T>();
+            States = new List<TrackingState>();
+
+            DetectedObjects.Add(detectedObject);
+            States.Add(TrackingState.Detected);
+            NumFramesInCurrentState = 1;
+        }
+
+        public abstract float getSimilarity(T detectedObject);
+
+        public virtual void updateFrame(T detectedObject)
+        {
+            if (detectedObject != null)
+                detectedObject.setTracked(ID);
+
+            TrackingState previousState = CurrentState;
+            TrackingState newState = getNewState(detectedObject);
+
+            if (!wasTrackedBefore && newState == TrackingState.Tracked)
+                wasTrackedBefore = true;
+
+            DetectedObjects.Add(detectedObject);
+            States.Add(newState);
+
+            if (previousState == newState)
+                NumFramesInCurrentState++;
+            else
+                NumFramesInCurrentState = 1;
+          }
+
+        private TrackingState getNewState(T detectedObject)
+        {
+            TrackingState previousState = CurrentState;
+            TrackingState newState = TrackingState.Undefined;
+
+            if (detectedObject != null)
+            {
+                switch (previousState)
+                {
+                    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 (previousState == TrackingState.Lost && NumFramesInCurrentState >= numFramesLostUntilDeleted)
+                newState = TrackingState.Deleted;
+            else
+                newState = TrackingState.Lost;
+
+            return newState;
+        }
+    }
+}

+ 65 - 108
bbiwarg/Recognition/Tracking/Tracker.cs

@@ -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);
     }
 }

+ 1 - 1
bbiwarg/Server/TUIO/TuioTime.cs

@@ -260,7 +260,7 @@ namespace TUIO
         }
 
 
-        public String ToString()
+        public override String ToString()
         {
             int mins = (int)((seconds % 3600) / 60);
             int secs = (int)(seconds % 60);

+ 8 - 8
bbiwarg/Server/TuioCommunicator.cs

@@ -20,21 +20,21 @@ namespace bbiwarg.Server
             cursors = new Dictionary<int, TuioCursor>();
         }
 
-        public void touchDown(object sender, PalmTouchEventArgs ptea)
+        public void touchDown(object sender, TouchEventArgs tea)
         {
-            TuioCursor cursor = server.addTuioCursor(ptea.Position.X, ptea.Position.Y);
-            cursors.Add(ptea.TrackID, cursor);
+            TuioCursor cursor = server.addTuioCursor(tea.RelativePosition.X, tea.RelativePosition.Y);
+            cursors.Add(tea.TrackID, cursor);
         }
 
-        public void touchMove(object sender, PalmTouchEventArgs ptea)
+        public void touchMove(object sender, TouchEventArgs tea)
         {
-            server.updateTuioCursor(cursors[ptea.TrackID], ptea.Position.X, ptea.Position.Y);
+            server.updateTuioCursor(cursors[tea.TrackID], tea.RelativePosition.X, tea.RelativePosition.Y);
         }
 
-        public void touchUp(object sender, PalmTouchEventArgs ptea)
+        public void touchUp(object sender, TouchEventArgs tea)
         {
-            server.removeTuioCursor(cursors[ptea.TrackID]);
-            cursors.Remove(ptea.TrackID);
+            server.removeTuioCursor(cursors[tea.TrackID]);
+            cursors.Remove(tea.TrackID);
         }
 
         public void close()

+ 5 - 3
bbiwarg/bbiwarg.csproj

@@ -77,10 +77,10 @@
     <Compile Include="Recognition\FingerRecognition\FingerSliceTrail.cs" />
     <Compile Include="Recognition\FingerRecognition\FingerSlice.cs" />
     <Compile Include="Recognition\FingerRecognition\FingerTracker.cs" />
+    <Compile Include="Recognition\FingerRecognition\TrackedFinger.cs" />
     <Compile Include="Recognition\HandRecognition\Hand.cs" />
     <Compile Include="Recognition\HandRecognition\HandDetector.cs" />
     <Compile Include="Recognition\PalmRecognition\PalmDetector.cs" />
-    <Compile Include="Recognition\TouchRecognition\PalmTouchEvent.cs" />
     <Compile Include="Recognition\TouchRecognition\TouchDetector.cs" />
     <Compile Include="Recognition\TouchRecognition\TouchEvent.cs" />
     <Compile Include="Recognition\TouchRecognition\TouchTracker.cs" />
@@ -91,10 +91,12 @@
     <Compile Include="Graphics\OutputImage.cs" />
     <Compile Include="MainBBWIWARG.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Recognition\Tracking\SimilarityContainer.cs" />
+    <Compile Include="Recognition\TouchRecognition\TrackedTouchEvent.cs" />
+    <Compile Include="Recognition\Tracking\Similarity.cs" />
     <Compile Include="Recognition\Tracking\TrackableObject.cs" />
-    <Compile Include="Recognition\Tracking\TrackableObjectHistory.cs" />
+    <Compile Include="Recognition\Tracking\TrackedObject.cs" />
     <Compile Include="Recognition\Tracking\Tracker.cs" />
+    <Compile Include="Recognition\Tracking\TrackIDPool.cs" />
     <Compile Include="Server\OSC.NET\OSCBundle.cs" />
     <Compile Include="Server\OSC.NET\OSCMessage.cs" />
     <Compile Include="Server\OSC.NET\OSCPacket.cs" />