Browse Source

Merge branch 'master' of https://git.tk.informatik.tu-darmstadt.de/etri-smartspaces

Anton Rohr 11 years ago
parent
commit
fe981d347c

+ 12 - 1
bbiwarg/Constants.cs

@@ -21,6 +21,7 @@ namespace bbiwarg
 
         public static readonly Color TouchEventDetectedColor = ColorDetected;
         public static readonly Color TouchEventTrackedColor = ColorTracked;
+        public static readonly Color TouchEventTipColor = Color.CornflowerBlue;
         public static readonly Color TouchEventAreaMatchedSubtractColor = Color.DarkOrange;
         public static readonly Color TouchEventAreaNonMatchedSubtractColor = Color.DarkSlateGray;
         public static readonly Color TouchEventStatusBarColor = Color.Green;
@@ -34,9 +35,19 @@ namespace bbiwarg
         public static readonly Color PalmConvexHullColor = Color.Green;
         public static readonly Color PalmThumbDefectColor = Color.Lime;
 
+        // finger detection
+        public static readonly int FingerStepSize = 2;
+        public static readonly int FingerMinNumSlices = 7;
+        public static readonly int FingerRemoveNumSlicesForCorrection = 3;
+        public static readonly int FingerMaxGapCounter = 10;
+        public static readonly int FingerMaxSliceDifferencePerStep = 5;
+        public static readonly int FingerMaxSize = 35;
+        public static readonly int FingerMinSize = 5;
+
         // palm detection
         public static readonly float PalmMinDefectMidFingerLineDistance = 20; // defects with mid point ((start + end) / 2) closer than this to a finger line are removed 
-    
+        public static readonly float PalmMaxThumbDefectAngle = 100; // degree
+
         //palm Grid
         public static readonly int PalmGridRows = 4;
         public static readonly int PalmGridColumns = 3;

+ 17 - 32
bbiwarg/Detectors/Fingers/FingerDetector.cs

@@ -31,15 +31,12 @@ namespace bbiwarg.Detectors.Fingers
 
         private void findFingers()
         {
-            int minNumSlices = 7;
-            int width = depthImage.Width;
-            int height = depthImage.Height;
-            int maxX = width - 1;
-            int maxY = height - 1;
+            int maxX = depthImage.Width - 1;
+            int maxY = depthImage.Height - 1;
 
             Fingers = new List<Finger>();
 
-            for (int y = 1; y < maxY; y+=5) //y++ for 100% coverage, but y++ for 99% coverage and 3 times better perfomance
+            for (int y = 1; y < maxY; y += 5) //y++ for 100% coverage, but y++ for 99% coverage and 3 times better perfomance
             {
                 for (int x = 1; x < maxX; x++)
                 {
@@ -57,7 +54,7 @@ namespace bbiwarg.Detectors.Fingers
                             if (slice != null)
                             {
                                 FingerSliceTrail trail = findFingerSliceTrail(slice, edgeDirection);
-                                if (trail != null && trail.NumSlices > minNumSlices)
+                                if (trail != null && trail.NumSlices > Constants.FingerMinNumSlices)
                                     createFingerFromTrail(trail);
                             }
                         }
@@ -80,16 +77,13 @@ namespace bbiwarg.Detectors.Fingers
 
         private FingerSliceTrail findFingerSliceTrail(FingerSlice startSlice, Vector2D startDirection)
         {
-            int minNumSlicesForCorrection = 7;
-            int numRemoveForCorrection = 3;
-
             int maxX = depthImage.Width - 1;
             int maxY = depthImage.Height - 1;
 
             FingerSliceTrail trail = new FingerSliceTrail(startSlice);
 
             Vector2D direction = startDirection;
-            Vector2D position = startSlice.Mid + 2*direction;
+            Vector2D position = startSlice.Mid + Constants.FingerStepSize * direction;
 
             if (position.isWithin(0, 0, maxX, maxY))
             {
@@ -99,9 +93,9 @@ namespace bbiwarg.Detectors.Fingers
                     trail.addSlice(nextSlice);
                     trail = expandTrail(trail);
 
-                    if (trail.NumSlices > minNumSlicesForCorrection)
+                    if (trail.NumSlices > Constants.FingerMinNumSlices)
                     {
-                        trail.Slices.RemoveRange(0, numRemoveForCorrection);
+                        trail.Slices.RemoveRange(0, Constants.FingerRemoveNumSlicesForCorrection);
                         trail.Slices.Reverse();
                         trail = expandTrail(trail);
                         trail.Slices.Reverse();
@@ -120,7 +114,7 @@ namespace bbiwarg.Detectors.Fingers
             int maxY = depthImage.Height - 1;
 
             Vector2D currentDirection = trail.getEndDirection();
-            Vector2D currentPosition = trail.End.Mid + 2*currentDirection;
+            Vector2D currentPosition = trail.End.Mid + Constants.FingerStepSize * currentDirection;
 
             int gapCounter = 0;
             int numSlices = trail.NumSlices;
@@ -128,16 +122,16 @@ namespace bbiwarg.Detectors.Fingers
             FingerSlice lastSlice = trail.End;
             FingerSlice nextSlice;
 
-            while (currentPosition.isWithin(0, 0, maxX, maxY) && gapCounter <= Math.Min(numSlices, 10))
+            while (currentPosition.isWithin(0, 0, maxX, maxY) && gapCounter <= Math.Min(numSlices, Constants.FingerMaxGapCounter))
             {
                 nextSlice = findFingerSliceFromMid(currentPosition, currentDirection);
-                if (nextSlice != null && (nextSlice.Length < lastSlice.Length + 5 && nextSlice.Length > lastSlice.Length - 5))
+                if (nextSlice != null && Math.Abs(nextSlice.Length - lastSlice.Length) <= Constants.FingerMaxSliceDifferencePerStep)
                 {
                     gapCounter = 0;
                     numSlices++;
                     trail.addSlice(nextSlice);
                     currentDirection = trail.getEndDirection();
-                    currentPosition = nextSlice.Mid + 2*currentDirection;
+                    currentPosition = nextSlice.Mid + Constants.FingerStepSize * currentDirection;
 
                     lastSlice = nextSlice;
                 }
@@ -168,7 +162,6 @@ namespace bbiwarg.Detectors.Fingers
         }
         private FingerSlice findFingerSliceFromStartEdge(Vector2D start, Vector2D direction)
         {
-
             Vector2D end = findNextEdge(start, direction);
             if (end == null) return null;
 
@@ -180,8 +173,6 @@ namespace bbiwarg.Detectors.Fingers
             int maxX = depthImage.Width - 1;
             int maxY = depthImage.Height - 1;
 
-            int maxFingerSize = 35;
-
             int maxStepsX;
             if (direction.X > 0)
                 maxStepsX = (int)((maxX - start.X) / direction.X);
@@ -198,7 +189,7 @@ namespace bbiwarg.Detectors.Fingers
             else
                 maxStepsY = int.MaxValue;
 
-            int maxStepsLength = (int)(maxFingerSize / direction.Length);
+            int maxStepsLength = (int)(Constants.FingerMaxSize / direction.Length);
 
             int maxSteps = Math.Min(maxStepsLength, Math.Min(maxStepsX, maxStepsY));
 
@@ -220,18 +211,12 @@ namespace bbiwarg.Detectors.Fingers
             int maxX = depthImage.Width - 1;
             int maxY = depthImage.Height - 1;
 
-            int minFingerSize = 5;
-            int maxFingerSize = 35;
-
             Vector2D direction = (end - start).normalize();
-            Vector2D beforeStart = start - direction;
-            Vector2D behindEnd = end + direction;
+            Vector2D beforeStart = (start - direction).moveInBound(0, 0, maxX, maxY);
+            Vector2D behindEnd = (end + direction).moveInBound(0, 0, maxY, maxY);
 
-            start = beforeStart.isWithin(0, 0, maxX, maxY) ? beforeStart : start;
-            end = behindEnd.isWithin(0, 0, maxX, maxY) ? behindEnd : end;
-
-            FingerSlice slice = new FingerSlice(start, end);
-            if (slice.Length >= minFingerSize && slice.Length <= maxFingerSize && fingerSliceDepthTest(slice))
+            FingerSlice slice = new FingerSlice(beforeStart, behindEnd);
+            if (slice.Length >= Constants.FingerMinSize && slice.Length <= Constants.FingerMaxSize && fingerSliceDepthTest(slice))
                 return slice;
 
             return null;
@@ -254,7 +239,7 @@ namespace bbiwarg.Detectors.Fingers
 
             //draw finger
             drawDetectedFinger(finger);
-        
+
             //remove edges around detected finger to improve performance
             edgeImage.removeFingerEdges(finger);
         }

+ 1 - 1
bbiwarg/Detectors/Fingers/FingerSliceTrail.cs

@@ -13,7 +13,7 @@ namespace bbiwarg.Detectors.Fingers
         public FingerSlice Start { get { return Slices[0]; } }
         public FingerSlice End { get { return Slices[Slices.Count - 1]; } }
         public int NumSlices { get { return Slices.Count; } }
-        public LineSegment2D LineSegment { get { return new LineSegment2D(Start.Mid, End.Mid); } }
+        public LineSegment2D LineSegment { get { return new LineSegment2D(End.Mid, Start.Mid); } }
 
         public FingerSliceTrail(FingerSlice slice)
         {

+ 69 - 28
bbiwarg/Detectors/Palm/PalmDetector.cs

@@ -18,9 +18,8 @@ namespace bbiwarg.Detectors.Palm
     class PalmDetector
     {
         private int width, height;
-        private DepthImage depthImage;
-        private EdgeImage edgeImage;
         private OutputImage outputImage;
+        private EdgeImage edgeImage;
 
         private Image<Gray, Byte> handImage;
         private Image<Gray, Byte> pointingHandMask;
@@ -33,7 +32,7 @@ namespace bbiwarg.Detectors.Palm
         private Vector2D thumbDefectEnd;
         private Vector2D thumbDefectDepth;
         
-        private static Kalman2DPositionFilter thumbDefectDepthFilter, thumbDefectStartFilter, thumbDefectEndFilter;
+        private Kalman2DPositionFilter thumbDefectDepthFilter, thumbDefectStartFilter, thumbDefectEndFilter;
 
         private bool valid = false;
         private Vector2D topLeft;
@@ -41,25 +40,31 @@ namespace bbiwarg.Detectors.Palm
         private Vector2D bottomLeft;
         private Vector2D bottomRight;
 
-        public Quadrangle PalmQuad;
+        public Quadrangle PalmQuad { get; private set; }
 
-        public PalmDetector(DepthImage depthImage, EdgeImage edgeImage, List<Finger> detectedFingers, OutputImage outputImage)
+        public PalmDetector()
         {
             // TODO: determine which fingers are index or thumb-fingers and detect palm in thumb-hand
+            thumbDefectDepthFilter = new Kalman2DPositionFilter(1.0e-2f, 1.0e-2f);
+            thumbDefectStartFilter = new Kalman2DPositionFilter(1.0e-2f, 1.0e-2f);
+            thumbDefectEndFilter = new Kalman2DPositionFilter(1.0e-2f, 1.0e-2f);
+        }
+
+        public void findPalmQuad(DepthImage depthImage, EdgeImage edgeImage, OutputImage outputImage, List<Finger> trackedFingers)
+        {
+            this.width = depthImage.Width;
+            this.height = depthImage.Height;
 
-            width = depthImage.Width;
-            height = depthImage.Height;
-            this.depthImage = depthImage;
             this.edgeImage = edgeImage;
             this.outputImage = outputImage;
 
             // dst = (src > (MaxDepth - MinDepth)) ? 0 : 1
             handImage = depthImage.Image.ThresholdBinaryInv(new Gray(depthImage.MaxDepth - depthImage.MinDepth - 1), new Gray(1)).Convert<Gray, Byte>();
 
-            fingers = getFingersWithoutThumb(detectedFingers);
+            fingers = getFingersWithoutThumb(trackedFingers);
             buildPointingHandMask();
             handImage = handImage.And(pointingHandMask);
-            
+
             findLongestPalmContour();
             if (palmContour != null)
             {
@@ -75,11 +80,11 @@ namespace bbiwarg.Detectors.Palm
             }
         }
 
-        public static void resetFilter()
+        public void resetFilters()
         {
-            thumbDefectDepthFilter = null;
-            thumbDefectStartFilter = null;
-            thumbDefectEndFilter = null;
+            thumbDefectDepthFilter.reset();
+            thumbDefectStartFilter.reset();
+            thumbDefectEndFilter.reset();
         }
 
         private List<Finger> getFingersWithoutThumb(List<Finger> detectedFingers)
@@ -138,11 +143,11 @@ namespace bbiwarg.Detectors.Palm
             if (finger == null)
                 return new Point(0, 0);
             Vector2D direction = (finger.Hand - finger.Tip).normalize();
-            Vector2D pos = finger.Hand + 20 * direction;
-            return new Point(HelperFunctions.thresholdRange<int>(0, width - 1, pos.IntX), HelperFunctions.thresholdRange<int>(0, height - 1, pos.IntY));
+            Vector2D pos = (finger.Hand + 20 * direction).moveInBound(0,0,width-1,height-1);
+            return pos;
         }
 
-        //public OutputImage i1, i2, i3, i4, i5, i6, i7, i8, i9;
+        public OutputImage i1, i2, i3, i4, i5, i6, i7, i8, i9;
         private void buildPointingHandMask()
         {
             /*i1 = new OutputImage(width, height);
@@ -193,6 +198,12 @@ namespace bbiwarg.Detectors.Palm
 
         private void findLongestPalmContour()
         {
+            i1 = new OutputImage(width, height);
+            i1.Image[0] = i1.Image[1] = i1.Image[2] = handImage * 255;
+
+            i2 = new OutputImage(width, height);
+            i2.Image[0] = i2.Image[1] = i2.Image[2] = pointingHandMask * 255;
+
             Contour<Point> contour = handImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL);
 
             palmContour = contour;
@@ -242,20 +253,46 @@ namespace bbiwarg.Detectors.Palm
             convexityDefects = newDefects;
         }
 
-        private void findHandPoints()
+        private MCvConvexityDefect? findThumbDefect()
         {
-            if (convexityDefects.Count > 0)
+            foreach (MCvConvexityDefect d in convexityDefects)
             {
-                MCvConvexityDefect thumbDefect = convexityDefects[0];
+                Vector2D depth = new Vector2D(d.DepthPoint);
+                Vector2D start = new Vector2D(d.StartPoint);
+                Vector2D end = new Vector2D(d.EndPoint);
+
+                float angle = (float) ((depth - start).getAngleBetween(depth - end) * 180 / Math.PI);
 
-                thumbDefectDepth = new Vector2D(thumbDefect.DepthPoint);
-                thumbDefectStart = new Vector2D(thumbDefect.StartPoint);
-                thumbDefectEnd = new Vector2D(thumbDefect.EndPoint);
-                if (thumbDefectDepthFilter == null)
+                if (angle <= Constants.PalmMaxThumbDefectAngle)
+                    return d;
+            }
+            return null;
+        }
+
+        private void findHandPoints()
+        {
+            MCvConvexityDefect? thumbDefect = findThumbDefect();
+
+            if (convexityDefects.Count > 0 && (thumbDefect != null || thumbDefectDepthFilter.Initialized))
+            {
+                if (thumbDefect != null)
                 {
-                    thumbDefectDepthFilter = new Kalman2DPositionFilter(thumbDefectDepth, 1.0e-2f, 1.0e-2f);
-                    thumbDefectStartFilter = new Kalman2DPositionFilter(thumbDefectStart, 1.0e-2f, 1.0e-2f);
-                    thumbDefectEndFilter = new Kalman2DPositionFilter(thumbDefectEnd, 1.0e-2f, 1.0e-2f);
+                    thumbDefectDepth = new Vector2D(thumbDefect.Value.DepthPoint);
+                    thumbDefectStart = new Vector2D(thumbDefect.Value.StartPoint);
+                    thumbDefectEnd = new Vector2D(thumbDefect.Value.EndPoint);
+                }
+                
+                if (!thumbDefectDepthFilter.Initialized)
+                {
+                    thumbDefectDepthFilter.setInitialPosition(thumbDefectDepth);
+                    thumbDefectStartFilter.setInitialPosition(thumbDefectStart);
+                    thumbDefectEndFilter.setInitialPosition(thumbDefectEnd);
+                }
+                else if (thumbDefect == null)
+                {
+                    thumbDefectDepth = thumbDefectDepthFilter.getPrediction();
+                    thumbDefectStart = thumbDefectStartFilter.getPrediction();
+                    thumbDefectEnd = thumbDefectEndFilter.getPrediction();
                 }
                 else
                 {
@@ -304,7 +341,11 @@ namespace bbiwarg.Detectors.Palm
 
             if (PalmQuad != null)
             {
-                outputImage.drawLineSegment(new Utility.LineSegment2D(thumbDefectDepth, (thumbDefectStart + thumbDefectEnd) / 2.0f), Constants.PalmThumbDefectColor, 1);
+                outputImage.fillCircle(thumbDefectDepth.IntX, thumbDefectDepth.IntY, 3, Color.Red);
+                outputImage.fillCircle(thumbDefectStart.IntX, thumbDefectStart.IntY, 3, Color.Green);
+                outputImage.fillCircle(thumbDefectEnd.IntX, thumbDefectEnd.IntY, 3, Color.Blue);
+
+                //outputImage.drawLineSegment(new Utility.LineSegment2D(thumbDefectDepth, (thumbDefectStart + thumbDefectEnd) / 2.0f), Constants.PalmThumbDefectColor, 1);
                 
                 Vector2D[] vertices = PalmQuad.Vertices;
                 for (int i = 0; i < 4; ++i)

+ 4 - 5
bbiwarg/Detectors/Touch/TouchDetector.cs

@@ -33,16 +33,15 @@ namespace bbiwarg.Detectors.Touch
             {
                 Vector2D tipPoint = finger.Tip;
 
+                outputImage.fillCircle(tipPoint.IntX, tipPoint.IntY, 3, Constants.TouchEventTipColor);
+
                 float floodValue = getFloodValue(tipPoint);
                 if (floodValue > floodValueThreshold)
                 {
                     //correct touchEvent position
                     Vector2D direction = finger.LineSegment.Line.Direction;
-                    float directionFactor = 10;
-                    float x = HelperFunctions.thresholdRange<float>(0, depthImage.Width - 1, tipPoint.X + directionFactor * direction.X);
-                    float y = HelperFunctions.thresholdRange<float>(0, depthImage.Height - 1, tipPoint.Y + directionFactor * direction.Y);
-                    Vector2D tep = new Vector2D(x, y);
-
+                    Vector2D tep = (tipPoint + 5 * direction).moveInBound(0,0,depthImage.Width-1,depthImage.Height-1);
+                    
                     outputImage.fillCircle(tep.IntX, tep.IntY, 5, Constants.TouchEventDetectedColor);
                     TouchEvent touchEvent = new TouchEvent(tep, floodValue, finger);
                     TouchEvents.Add(touchEvent);

+ 2 - 2
bbiwarg/Graphics/OutputWindow.cs

@@ -25,7 +25,7 @@ namespace bbiwarg.Graphics
         private Stopwatch watch;
 
         public OutputWindow(VideoHandle videoHandle)
-            : base((int) (Constants.WindwoSizeFactor * HelperFunctions.thresholdRange<int>(1, Constants.NumImagesPerRow, videoHandle.OutputImages.Length) * videoHandle.Width), 
+            : base((int) (Constants.WindwoSizeFactor * Math.Max(1, Math.Min(Constants.NumImagesPerRow, videoHandle.OutputImages.Length)) * videoHandle.Width), 
                    (int) (Constants.WindwoSizeFactor * (1 + (videoHandle.OutputImages.Length - 1) / Constants.NumImagesPerRow) * videoHandle.Height))
         {
             this.videoHandle = videoHandle;
@@ -165,7 +165,7 @@ namespace bbiwarg.Graphics
 
             Timer.stop("onRenderFrame");
             
-            Timer.outputAll();
+            //Timer.outputAll();
         }
 
     }

+ 2 - 2
bbiwarg/Graphics/TouchEventVisualizer.cs

@@ -30,13 +30,13 @@ namespace bbiwarg.Graphics
 
         public void addPalmTouchEvent(PalmTouchEvent e, int currentFrame)
         {
-
             Vector2D pos;
             if (lastUpdated == -1 || (currentFrame - lastUpdated) > 5 || currentTouchPositions == null || kalmanFilter == null)
             {
                 lastTouchPositions = currentTouchPositions;
                 currentTouchPositions = new List<Vector2D>();
-                kalmanFilter = new Kalman2DPositionFilter(e.RelativePalmPosition);
+                kalmanFilter = new Kalman2DPositionFilter();
+                kalmanFilter.setInitialPosition(e.RelativePalmPosition);
                 pos = e.RelativePalmPosition;
             }
             else

+ 0 - 20
bbiwarg/Utility/HelperFunctions.cs

@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace bbiwarg.Utility
-{
-    public static class HelperFunctions
-    {
-        public static T thresholdRange<T>(T min, T max, T value)
-        {
-            if (Comparer<T>.Default.Compare(min, value) > 0)
-                return min;
-            if (Comparer<T>.Default.Compare(value, max) > 0)
-                return max;
-            return value;
-        }
-    }
-}

+ 28 - 5
bbiwarg/Utility/Kalman2DPositionFilter.cs

@@ -12,21 +12,27 @@ namespace bbiwarg.Utility
     class Kalman2DPositionFilter
     {
         private Kalman kalman;
+        private float measurementNoiseFactor, processNoiseFactor;
+
+        public bool Initialized { get; private set; }
 
         // state: x, y, v_x, v_y
         //   x: current x position
         //   y: current y position
         // v_x: velocity in x direction
         // v_y: velocity in y direction
-        public Kalman2DPositionFilter(Vector2D initialPosition, float measurementNoiseFactor = 1.0e-1f, float processNoiseFactor = 1.0e-4f)
+        public Kalman2DPositionFilter(float measurementNoiseFactor = 1.0e-1f, float processNoiseFactor = 1.0e-4f)
+        {
+            this.measurementNoiseFactor = measurementNoiseFactor;
+            this.processNoiseFactor = processNoiseFactor;
+            reset();
+        }
+
+        public void reset()
         {
             // 4 state variables and 2 measurements (0 controls)
             kalman = new Kalman(4, 2, 0);
 
-            // initial state (x, y, v_x, v_y)
-            Matrix<float> initialState = new Matrix<float>(new float[] { initialPosition.X, initialPosition.Y, 0.0f, 0.0f });
-            kalman.CorrectedState = initialState;
-
             // transition matrix 
             Matrix<float> transitionMatrix = new Matrix<float>(new float[,] 
             { {1.0f, 0.0f, 1.0f, 0.0f},   // x = x + v_x
@@ -56,6 +62,23 @@ namespace bbiwarg.Utility
             Matrix<float> errorCovariancePostMatrix = new Matrix<float>(4, 4);
             errorCovariancePostMatrix.SetIdentity();
             kalman.ErrorCovariancePost = errorCovariancePostMatrix;
+
+            Initialized = false;
+        }
+
+        public void setInitialPosition(Vector2D initialPosition)
+        {
+            // initial state (x, y, v_x, v_y)
+            Matrix<float> initialState = new Matrix<float>(new float[] { initialPosition.X, initialPosition.Y, 0.0f, 0.0f });
+            kalman.CorrectedState = initialState;
+
+            Initialized = true;
+        }
+
+        public Vector2D getPrediction()
+        {
+            Matrix<float> predicton = kalman.Predict();
+            return new Vector2D(predicton[0, 0], predicton[1, 0]);
         }
 
         // updates the filter and returns the corrected position

+ 1 - 1
bbiwarg/Utility/LineSegment2D.cs

@@ -26,7 +26,7 @@ namespace bbiwarg.Utility
             P2 = p2;
 
             //line
-            Line = new Line2D(P1, P1 - P2);
+            Line = new Line2D(P1, P2-P1);
         }
 
         public float getParallelDistanceTo(LineSegment2D line)

+ 7 - 0
bbiwarg/Utility/Vector2D.cs

@@ -86,6 +86,13 @@ namespace bbiwarg.Utility
             return (X >= minX && Y >= minY && X <= maxX && Y <= maxY);
         }
 
+        public Vector2D moveInBound(float minX, float minY, float maxX, float maxY)
+        {
+            float x = Math.Min(maxX, Math.Max(minX, X));
+            float y = Math.Min(maxY, Math.Max(minY, Y));
+            return new Vector2D(x, y);
+        }
+
         public Vector2D getOrthogonal(bool side)
         {
             if (side)

+ 7 - 4
bbiwarg/VideoHandle.cs

@@ -64,6 +64,8 @@ namespace bbiwarg
 
         public void start()
         {
+            palmDetector = new PalmDetector();
+
             inputProvider.init();
             inputProvider.start();
             inputProvider.updateFrame();
@@ -169,14 +171,15 @@ namespace bbiwarg
 
             //detect palm
             Timer.start("palmDetection");
-            palmDetector = new PalmDetector(depthImage, edgeImage, fingerDetector.Fingers, OutputImages[2]);
-            if (sourceIsMovie() && CurrentFrame == 0)
-                PalmDetector.resetFilter();
+            if (fingerTracker.TrackedFingers.Count >= 2)
+                palmDetector.findPalmQuad(depthImage, edgeImage, OutputImages[2], fingerTracker.TrackedFingers);
+            if (CurrentFrame == 0)
+                palmDetector.resetFilters();
             Timer.stop("palmDetection");
 
             //detect touchEvents
             Timer.start("touchDetection");
-            touchDetector = new TouchDetector(fingerTracker.TrackedFingers, depthImage, OutputImages[2]);
+            touchDetector = new TouchDetector(fingerTracker.TrackedFingers, depthImage, OutputImages[0]);
             if (palmDetector.PalmQuad != null)
                 palmTouchDetector = new PalmTouchDetector(touchDetector.TouchEvents, palmDetector.PalmQuad);
             Timer.stop("touchDetection");

+ 0 - 1
bbiwarg/bbiwarg.csproj

@@ -88,7 +88,6 @@
     <Compile Include="InputProvider\IisuInputProvider.cs" />
     <Compile Include="MainBBWIWARG.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Utility\HelperFunctions.cs" />
     <Compile Include="Utility\Kalman2DPositionFilter.cs" />
     <Compile Include="Utility\Line2D.cs" />
     <Compile Include="Utility\LineSegment2D.cs" />