瀏覽代碼

improved fingerDetection (start+end)

Alexander Hendrich 11 年之前
父節點
當前提交
1fb3af22d1

+ 64 - 50
bbiwarg/Detectors/Fingers/Finger.cs

@@ -13,43 +13,37 @@ namespace bbiwarg.Detectors.Fingers
     class Finger
     {
         private List<FingerPoint> fingerPoints;
-        private FingerPoint nearest;
-        private FingerPoint farthest;
+        private bool lineUpToDate = false;
         private PointF direction;
         private PointF pointOnLine;
-        private PointF start;
-        private PointF end;
-        private bool lineUpToDate;
-
+        private PointF lineEndPoint1;
+        private PointF lineEndPoint2;
+        private FingerPoint tipPoint;
+        private FingerPoint handPoint;
+        private float length;
+        
         public Finger(FingerPoint fingerPoint)
         {
             fingerPoints = new List<FingerPoint>();
-            nearest = fingerPoint;
-            farthest = fingerPoint;
-            lineUpToDate = false;
             addFingerPoint(fingerPoint);
         }
 
-        public FingerPoint getNearest()
+        public PointF getLineEndPoint1()
         {
-            return nearest;
-        }
-
-        public FingerPoint getFarthest()
-        {
-            return farthest;
+            if (!lineUpToDate) updateLine();
+            return lineEndPoint1;
         }
 
-        public PointF getStart()
+        public PointF getLineEndPoint2()
         {
             if (!lineUpToDate) updateLine();
-            return start;
+            return lineEndPoint2;
         }
 
-        public PointF getEnd()
+        public FingerPoint getTipPoint()
         {
             if (!lineUpToDate) updateLine();
-            return end;
+            return tipPoint;
         }
 
         public PointF getDirection() {
@@ -57,16 +51,15 @@ namespace bbiwarg.Detectors.Fingers
             return direction;
         }
 
+        public float getLength()
+        {
+            if (!lineUpToDate) updateLine();
+            return length;
+        }
+
         public void addFingerPoint(FingerPoint fingerPoint)
         {
             fingerPoints.Add(fingerPoint);
-
-            //update nearest
-            if (fingerPoint.getDepth() < nearest.getDepth()) nearest = fingerPoint;
-
-            //update farthest
-            if (fingerPoint.getDepth() > farthest.getDepth()) farthest = fingerPoint;
-
             lineUpToDate = false;
         }
 
@@ -85,27 +78,6 @@ namespace bbiwarg.Detectors.Fingers
             return minDinstance;
         }
 
-        public float getLength()
-        {
-            FingerPoint fp1 = getNearest();
-            FingerPoint fp2 = getFarthest();
-            float distance = fp1.getDistanceTo(fp2);
-            return distance;
-        }
-
-        private PointF projectToLine(PointF p)
-        {
-            float px = p.X, py = p.Y, dx = direction.X, dy = direction.Y, ox = pointOnLine.X, oy = pointOnLine.Y;
-            float diffx = px - ox;
-            float diffy = py - oy;
-
-            float diff_d = (diffx * dx + diffy * dy);
-            float d_d = (dx * dx + dy * dy);
-            float q = diff_d / d_d;
-
-            return new PointF(ox + q * dx, oy + q * dy);
-        }
-
         private void updateLine() {
             //update direction+pointonline
             PointF[] pointArray = new PointF[fingerPoints.Count];
@@ -117,11 +89,53 @@ namespace bbiwarg.Detectors.Fingers
             }
             PointCollection.Line2DFitting(pointArray, Emgu.CV.CvEnum.DIST_TYPE.CV_DIST_L2, out direction, out pointOnLine);
 
+            FingerPoint fp1 = fingerPoints[0];
+            FingerPoint fp2 = fingerPoints[0];
+            length = 0.0f;
+            foreach (FingerPoint fp in fingerPoints) {
+                float distanceToFP1 = fp.getDistanceTo(fp1);
+                float distanceToFP2 = fp.getDistanceTo(fp2);
+                if (length < distanceToFP1 && distanceToFP1 >= distanceToFP2) 
+                {
+                    fp2 = fp;
+                    length = distanceToFP1;
+                }
+                else if (length < distanceToFP2 && distanceToFP2 > distanceToFP1)
+                {
+                    fp1 = fp;
+                    length = distanceToFP2;
+                }
+            }
+
+            if (fp1.getY() < fp2.getY())
+            {
+                tipPoint = fp1;
+                handPoint = fp2;
+            }
+            else 
+            {
+                tipPoint = fp2;
+                handPoint = fp1;
+            }
+
             //update start+end
-            start = projectToLine(new PointF(farthest.getX(), farthest.getY()));
-            end = projectToLine(new PointF(nearest.getX(), nearest.getY()));
+            lineEndPoint1 = projectToLine(new PointF(tipPoint.getX(), tipPoint.getY()));
+            lineEndPoint2 = projectToLine(new PointF(handPoint.getX(), handPoint.getY()));
 
             lineUpToDate = true;
         }
+
+        private PointF projectToLine(PointF p)
+        {
+            float px = p.X, py = p.Y, dx = direction.X, dy = direction.Y, ox = pointOnLine.X, oy = pointOnLine.Y;
+            float diffx = px - ox;
+            float diffy = py - oy;
+
+            float diff_d = (diffx * dx + diffy * dy);
+            float d_d = (dx * dx + dy * dy);
+            float q = diff_d / d_d;
+
+            return new PointF(ox + q * dx, oy + q * dy);
+        }
     }
 }

+ 3 - 3
bbiwarg/Detectors/Fingers/FingerDetector.cs

@@ -161,9 +161,9 @@ namespace bbiwarg.Detectors.Fingers
             fingerPoints = new bool[width, height];
 
             foreach (Finger finger in fingers) {
-                PointF start = finger.getStart();
-                PointF end = finger.getEnd();
-                drawFingerPointLine(start, end);
+                PointF lineEndPoint1 = finger.getLineEndPoint1();
+                PointF lineEndPoint2 = finger.getLineEndPoint2();
+                drawFingerPointLine(lineEndPoint1, lineEndPoint2);
             }
         }
 

+ 7 - 15
bbiwarg/Detectors/Touch/TouchDetector.cs

@@ -23,29 +23,21 @@ namespace bbiwarg.Detectors.Touch
             this.touchImage = touchImage;
             this.fingers = fingers;
             this.touchEvents = new List<TouchEvent>();
-            float touchValueThreshold = 0.5f;
+            float floodValueThreshold = 0.5f;
 
             foreach (Finger finger in fingers) {
-                FingerPoint fp1 = finger.getFarthest();
-                FingerPoint fp2 = finger.getNearest();
-                FingerPoint fp;
+                FingerPoint tipPoint = finger.getTipPoint();
 
-
-                if (fp1.getY() < fp2.getY())
-                    fp = fp1;
-                else
-                    fp = fp2;
-
-                float touchValue = getTouchValueAt(fp.getX(), fp.getY());
-                if (touchValue > touchValueThreshold)
+                float floodValue = getFloodValue(tipPoint.getX(), tipPoint.getY());
+                if (floodValue > floodValueThreshold)
                 {
                     PointF direction = finger.getDirection();
                     float directionFactor = -10;
-                    PointF tep = new PointF(fp.getX() + directionFactor*direction.X, fp.getY() + directionFactor*direction.Y);
+                    PointF tep = new PointF(tipPoint.getX() + directionFactor*direction.X, tipPoint.getY() + directionFactor*direction.Y);
                     
 
                     touchImage.setTouchAt((int)tep.X, (int)tep.Y, TouchImageState.touchDetected);
-                    TouchEvent touchEvent = new TouchEvent((int)tep.X, (int)tep.Y, touchValue, finger);
+                    TouchEvent touchEvent = new TouchEvent((int)tep.X, (int)tep.Y, floodValue, finger);
                     touchEvents.Add(touchEvent);
                 }
             }
@@ -55,7 +47,7 @@ namespace bbiwarg.Detectors.Touch
             return touchEvents;
         }
 
-        private float getTouchValueAt(int touchX, int touchY) {
+        private float getFloodValue(int touchX, int touchY) {
             int searchSize = 15;
             int maxDepthDifference = 20;
             Int16 fingerDiameter = 7;

+ 5 - 5
bbiwarg/Detectors/Touch/TouchEvent.cs

@@ -11,13 +11,13 @@ namespace bbiwarg.Detectors.Touch
     {
         private int x;
         private int y;
-        private float touchValue;
+        private float floodValue;
         private Finger finger;
 
-        public TouchEvent(int x, int y, float touchValue, Finger finger) {
+        public TouchEvent(int x, int y, float floodValue, Finger finger) {
             this.x = x;
             this.y = y;
-            this.touchValue = touchValue;
+            this.floodValue = floodValue;
             this.finger = finger;
         }
 
@@ -29,8 +29,8 @@ namespace bbiwarg.Detectors.Touch
             return y;
         }
 
-        public float getTouchValue() {
-            return touchValue;
+        public float getFloodValue() {
+            return floodValue;
         }
 
         public float getDistanceTo(TouchEvent te) {

+ 8 - 4
bbiwarg/Detectors/Touch/TouchTracker.cs

@@ -51,21 +51,25 @@ namespace bbiwarg.Detectors.Touch
                 {
                     touchImage.setTouchAt(te.getX(), te.getY(), TouchImageState.touchTracked);
                     trackedTouchEvents.Add(te);
-                    Console.WriteLine("touch tracked at x:" + te.getX() + " y:" + te.getY() + " [touchValue:" + te.getTouchValue() + "]");
+                    Console.WriteLine("touch tracked at x:" + te.getX() + " y:" + te.getY() + " [floodValue:" + te.getFloodValue() + "]");
                 }
             }
         }
 
         private bool hasSimilarTouchEventInFrame(TouchEvent touchEvent, int frame) {
-            float maxDistance = 20;
-
             foreach (TouchEvent te in detectedTouchEvents[frame]) {
                 float distance = touchEvent.getDistanceTo(te);
-                if (distance < maxDistance)
+                if (compareTouchEvents(touchEvent, te))
                     return true;
             }
 
             return false;
         }
+
+        private bool compareTouchEvents(TouchEvent te1, TouchEvent te2) {
+            float maxDistance = 20;
+            float distance = te1.getDistanceTo(te2);
+            return (distance < maxDistance);
+        }
     }
 }