Kaynağa Gözat

reorganized hand/palm detection

Alexander Hendrich 10 yıl önce
ebeveyn
işleme
4844b2820e

+ 4 - 3
bbiwarg/Graphics/OutputImage.cs

@@ -67,14 +67,15 @@ namespace bbiwarg.Graphics
             Image.Draw(text, ref font, new Point(x, y), new Rgb(color));
         }
 
-        public void drawDefect(ConvexityDefect defect, Color pointColor, Color lineColor) {
+        public void drawDefect(ConvexityDefect defect, Color pointColor, Color lineColor)
+        {
             drawLineSegment(new Utility.LineSegment2D(defect.OuterShort, defect.Inner), lineColor);
             drawLineSegment(new Utility.LineSegment2D(defect.OuterLong, defect.Inner), lineColor);
-            
+
             fillCircle(defect.Inner.IntX, defect.Inner.IntY, 2, pointColor);
             fillCircle(defect.OuterShort.IntX, defect.OuterShort.IntY, 2, pointColor);
             fillCircle(defect.OuterLong.IntX, defect.OuterLong.IntY, 2, pointColor);
-                
+
         }
 
         public void drawImage(Image<Gray, byte> image, Color color)

+ 4 - 4
bbiwarg/InputHandler.cs

@@ -179,7 +179,7 @@ namespace bbiwarg
         private void detectHands()
         {
             Timer.start("detectHands");
-            handDetector = new HandDetector(depthImage, edgeImage, fingerTracker.Fingers);
+            handDetector = new HandDetector(depthImage, fingerTracker.Fingers);
             Timer.stop("detectHands");
         }
 
@@ -193,7 +193,7 @@ namespace bbiwarg
         private void detectPalm()
         {
             Timer.start("detectPalm\t");
-            palmDetector = new PalmDetector(handTracker.Hands);
+            palmDetector = new PalmDetector(depthImage, handTracker.Hands);
             Timer.stop("detectPalm\t");
         }
 
@@ -265,8 +265,8 @@ namespace bbiwarg
                 OutputImages[2].fillCircle(h.Centroid.IntX, h.Centroid.IntY, 5, Parameters.HandCentroidColor);
                 OutputImages[2].drawText(h.Centroid.IntX, h.Centroid.IntY, h.TrackID.ToString(), Parameters.HandIDColor);
 
-                if (h.ThumbDefect != null)
-                    OutputImages[2].drawDefect(h.ThumbDefect, Parameters.HandThumbDefectPointColor, Parameters.HandThumbDefectLineColor);
+                if (h.Palm != null)
+                    OutputImages[2].drawDefect(h.Palm.ThumbDefect, Parameters.HandThumbDefectPointColor, Parameters.HandThumbDefectLineColor);
             }
 
             //image3

+ 1 - 1
bbiwarg/Parameters.cs

@@ -107,7 +107,7 @@ namespace bbiwarg
         public static readonly float HandmYY = 0.0005f;
 
         // palm detection
-        public static readonly int PalmNumPositionsForHandWidth = 5;
+        public static readonly int PalmNumPositionsForPalmWidth = 5;
 
         // palm tracker
         public static readonly int PalmTrackerNumFramesDetectedUntilTracked = 5;

+ 5 - 86
bbiwarg/Recognition/HandRecognition/Hand.cs

@@ -13,30 +13,20 @@ using bbiwarg.Recognition.PalmRecognition;
 
 namespace bbiwarg.Recognition.HandRecognition
 {
-    public enum HandSide
-    {
-        Undefined = 0,
-        Right = 1,
-        Left = 2
-    }
-
     class Hand : TrackableObject
     {
-        public List<ConvexityDefect> ConvexityDefects { get; private set; }
         public Vector2D Centroid { get; private set; }
         public Image<Gray, byte> Mask { get; private set; }
         public List<Finger> Fingers { get; private set; }
-        public ConvexityDefect ThumbDefect { get; private set; }
-        public HandSide Side { get; private set; }
         public Palm Palm { get; set; }
 
-        public Hand(Image<Gray, byte> mask, Finger finger)
+        public Hand(Image<Gray, byte> mask, List<Finger> fingers)
         {
             Mask = mask;
-            Fingers = new List<Finger>();
+            Fingers = fingers;
 
-            addFinger(finger);
-            findCentroids();
+            foreach (Finger finger in Fingers)
+                finger.Hand = this;
         }
 
         public bool isInside(Vector2D point)
@@ -44,26 +34,17 @@ namespace bbiwarg.Recognition.HandRecognition
             return (Mask.Data[point.IntY, point.IntX, 0] != 0);
         }
 
-        public void addFinger(Finger finger)
-        {
-            Fingers.Add(finger);
-            finger.Hand = this;
-        }
-
         public void mergeWith(Hand mergeHand)
         {
             extendMask(mergeHand.Mask);
             Fingers.AddRange(mergeHand.Fingers);
             foreach (Finger finger in mergeHand.Fingers)
                 finger.Hand = this;
-            
-            findCentroids();
         }
 
         public void extendMask(Image<Gray, byte> extendMask)
         {
             Mask = Mask.Or(extendMask);
-            findCentroids();
         }
 
         public void fillOverlappingFingers(List<Finger> otherFingers)
@@ -91,72 +72,10 @@ namespace bbiwarg.Recognition.HandRecognition
             Mask = Mask.Dilate(1);
         }
 
-        public void findThumbDefect()
-        {
-            if (isThumbOnly())
-            {
-                findConvexityDefects();
-                filterThumbDefect();
-            }
-            determineHandSide();
-        }
-
-        private bool isThumbOnly()
-        {
-            return (Fingers.Count == 1);
-        }
-
-        private void findConvexityDefects()
-        {
-            using (MemStorage ms = new MemStorage())
-            {
-                Contour<Point> contour = Mask.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL);
-                List<MCvConvexityDefect> mcvConvexityDefects = new List<MCvConvexityDefect>(contour.GetConvexityDefacts(ms, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE));
-
-                ConvexityDefects = new List<ConvexityDefect>();
-                foreach (MCvConvexityDefect defect in mcvConvexityDefects)
-                    ConvexityDefects.Add(new ConvexityDefect(defect));
-            }
-        }
-
-        private void filterThumbDefect()
+        public void findCentroid()
         {
-            if (ConvexityDefects.Count > 0)
-            {
-                ConvexityDefects.Sort((cd1, cd2) => (cd2.Depth.CompareTo(cd1.Depth)));
-
-                Finger thumb = Fingers[0];
-
-                foreach (ConvexityDefect defect in ConvexityDefects)
-                {
-                    if (defect.isPossibleThumbDefect(thumb))
-                    {
-                        ThumbDefect = defect;
-                        break;
-                    }
-                }
-            }
-        }
-
-        private void determineHandSide()
-        {
-            if (ThumbDefect != null)
-            {
-                if (ThumbDefect.VectorShort.crossProduct(ThumbDefect.VectorLong) > 0)
-                    Side = HandSide.Left;
-                else
-                    Side = HandSide.Right;
-            }
-            else
-                Side = HandSide.Undefined;
-        }
-
-        private void findCentroids()
-        {
-            //find centroid
             MCvPoint2D64f gravityCenter = Mask.GetMoments(true).GravityCenter;
             Centroid = new Vector2D((float)gravityCenter.x, (float)gravityCenter.y);
         }
-
     }
 }

+ 32 - 50
bbiwarg/Recognition/HandRecognition/HandDetector.cs

@@ -18,7 +18,6 @@ namespace bbiwarg.Recognition.HandRecognition
     class HandDetector
     {
         private DepthImage depthImage;
-        private EdgeImage edgeImage;
         private Image<Gray, byte> modifiedHandDepthImage;
         private List<Finger> fingers;
         private Dictionary<Hand, List<Finger>> otherHandsFingers;
@@ -26,17 +25,15 @@ namespace bbiwarg.Recognition.HandRecognition
         public List<Hand> Hands { get; private set; }
         public Image<Gray, byte> HandMask { get; private set; }
 
-        public HandDetector(DepthImage depthImage, EdgeImage edgeImage, List<Finger> fingers)
+        public HandDetector(DepthImage depthImage, List<Finger> fingers)
         {
             this.depthImage = depthImage;
-            this.edgeImage = edgeImage;
             this.fingers = fingers;
 
             createModifiedHandEdgeImage();
             findHands();
-            findOtherHandsFingers();
             fixOverlappingFingers();
-            findThumbDefects();
+            findCentroids();
             createHandMask();
         }
 
@@ -55,45 +52,31 @@ namespace bbiwarg.Recognition.HandRecognition
         private void findHands()
         {
             Hands = new List<Hand>();
+            otherHandsFingers = new Dictionary<Hand,List<Finger>>();
+            List<Finger> assignedFingers = new List<Finger>();
 
             foreach (Finger finger in fingers)
             {
-                bool newHand = true;
-                foreach (Hand hand in Hands)
-                {
-                    if (hand.isInside(finger.HandPoint))
-                    {
-                        hand.addFinger(finger);
-                        newHand = false;
-                        break;
-                    }
-                }
-
-                if (newHand)
-                {
+                if(!assignedFingers.Contains(finger)) {
                     Image<Gray, byte> handMask = getHandMask(finger.HandPoint);
-                    int numPixels = handMask.CountNonzero()[0];
-                    if (numPixels < Parameters.HandMaxSize * Parameters.ImageNumPixels && numPixels > Parameters.HandMinSize * Parameters.ImageNumPixels)
-                    {
-                        Hand hand = new Hand(handMask, finger);
-                        Hands.Add(hand);
+
+                    List<Finger> fingersOnHand = new List<Finger>();
+                    List<Finger> fingersOnOtherHand = new List<Finger>();
+
+                    foreach (Finger f in fingers) {
+                        if (!assignedFingers.Contains(f) && handMask.Data[f.HandPoint.IntY, f.HandPoint.IntX, 0] != 0)
+                        {
+                            fingersOnHand.Add(f);
+                            assignedFingers.Add(f);
+                        }
+                        else
+                            fingersOnOtherHand.Add(f);  
                     }
-                }
-            }
-        }
 
-        private void findOtherHandsFingers()
-        {
-            otherHandsFingers = new Dictionary<Hand, List<Finger>>();
-            foreach (Hand hand in Hands)
-            {
-                List<Finger> otherFingers = new List<Finger>();
-                foreach (Finger finger in fingers)
-                {
-                    if (!hand.Fingers.Contains(finger))
-                        otherFingers.Add(finger);
+                    Hand hand = new Hand(handMask, fingersOnHand);
+                    otherHandsFingers.Add(hand, fingersOnOtherHand);
+                    Hands.Add(hand);
                 }
-                otherHandsFingers.Add(hand, otherFingers);
             }
         }
 
@@ -111,19 +94,6 @@ namespace bbiwarg.Recognition.HandRecognition
             fillOverlappingFingers();
         }
 
-        private void findThumbDefects()
-        {
-            foreach (Hand hand in Hands)
-                hand.findThumbDefect();
-        }
-
-        private void createHandMask()
-        {
-            HandMask = new Image<Gray, byte>(Parameters.ImageWidth, Parameters.ImageHeight);
-            foreach (Hand hand in Hands)
-                HandMask = HandMask.Or(hand.Mask);
-        }
-
         private void extendOrMergeThroughOverlappingFingers()
         {
             List<Hand> mergedHands = new List<Hand>();
@@ -210,5 +180,17 @@ namespace bbiwarg.Recognition.HandRecognition
                 hand.fillOverlappingFingers(otherHandsFingers[hand]);
             }
         }
+
+        private void findCentroids() {
+            foreach (Hand hand in Hands)
+                hand.findCentroid();
+        }
+
+        private void createHandMask()
+        {
+            HandMask = new Image<Gray, byte>(Parameters.ImageWidth, Parameters.ImageHeight);
+            foreach (Hand hand in Hands)
+                HandMask = HandMask.Or(hand.Mask);
+        }
     }
 }

+ 29 - 12
bbiwarg/Recognition/PalmRecognition/Palm.cs

@@ -3,44 +3,61 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using bbiwarg.Utility;
 using bbiwarg.Recognition.HandRecognition;
 using bbiwarg.Recognition.Tracking;
-using bbiwarg.Utility;
 
 namespace bbiwarg.Recognition.PalmRecognition
 {
-    class Palm : TrackableObject
+    public enum HandSide
     {
+        Undefined = 0,
+        Right = 1,
+        Left = 2
+    }
 
+    class Palm : TrackableObject
+    {
         public Hand Hand { get; private set; }
+        public ConvexityDefect ThumbDefect { get; private set; }
+        public HandSide HandSide { get; private set; }
         public Vector2D WristUpper { get; private set; }
-        public Vector2D WristLower { get; private set; }
         public Vector2D FingersUpper { get; private set; }
         public Vector2D FingersLower { get; private set; }
+        public Vector2D WristLower { get; private set; }
         public Quadrangle Quad { get; private set; }
 
-        public Palm(Hand hand, Vector2D wristUpper, Vector2D wristLower, Vector2D fingersLower, Vector2D fingersUpper)
+        public Palm(Hand hand, ConvexityDefect thumbDefect, HandSide handSide, Vector2D wristUpper, Vector2D fingersUpper, Vector2D fingersLower, Vector2D wristLower)
         {
             Hand = hand;
+            ThumbDefect = thumbDefect;
+            HandSide = handSide;
             WristUpper = wristUpper;
-            WristLower = wristLower;
             FingersUpper = fingersUpper;
             FingersLower = fingersLower;
+            WristLower = wristLower;
 
-            Hand.Palm = this;
+            hand.Palm = this;
 
-            if (Hand.Side == HandSide.Left)
-                Quad = new Quadrangle(WristUpper, FingersUpper, FingersLower, WristLower);
-            else
-                Quad = new Quadrangle(FingersUpper, WristUpper, WristLower, FingersLower);
+            createQuad();
         }
 
-        public Vector2D getRelativePosition(Vector2D absolutePosition) {
+        public Vector2D getRelativePosition(Vector2D absolutePosition)
+        {
             return Quad.getRelativePosition(absolutePosition);
         }
 
-        public bool isInside(Vector2D position) {
+        public bool isInside(Vector2D position)
+        {
             return Quad.isInside(position);
         }
+
+        private void createQuad()
+        {
+            if (HandSide == HandSide.Left)
+                Quad = new Quadrangle(WristUpper, FingersUpper, FingersLower, WristLower);
+            else
+                Quad = new Quadrangle(FingersUpper, WristUpper, WristLower, FingersLower);
+        }
     }
 }

+ 109 - 70
bbiwarg/Recognition/PalmRecognition/PalmDetector.cs

@@ -1,115 +1,154 @@
 using System;
 using System.Collections.Generic;
+using System.Drawing;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
-using bbiwarg.Recognition.HandRecognition;
+using bbiwarg.Images;
 using bbiwarg.Utility;
-using Emgu.CV.Structure;
+using bbiwarg.Recognition.FingerRecognition;
+using bbiwarg.Recognition.HandRecognition;
 using Emgu.CV;
+using Emgu.CV.Structure;
 
 namespace bbiwarg.Recognition.PalmRecognition
 {
     class PalmDetector
     {
+        private DepthImage depthImage;
         private List<Hand> hands;
-        private List<Hand> palmHands;
 
-        public List<Palm> Palms { get; private set; }
+        public List<Palm> Palms;
 
-        public PalmDetector(List<Hand> hands)
+        public PalmDetector(DepthImage depthImage, List<Hand> hands)
         {
+            this.depthImage = depthImage;
             this.hands = hands;
 
-            findPalmHands();
-            createPalms();
+            findPalms();
         }
 
-        private void findPalmHands()
-        {
-            palmHands = new List<Hand>();
-
-            foreach (Hand hand in hands)
-            {
-                if (hand.ThumbDefect != null)
-                    palmHands.Add(hand);
-            }
-        }
-
-        private void createPalms()
+        private void findPalms()
         {
             Palms = new List<Palm>();
-            foreach (Hand palmHand in palmHands)
+            foreach (Hand hand in hands)
             {
-                ConvexityDefect thumbDefect = palmHand.ThumbDefect;
-                Vector2D directionWristFinger = thumbDefect.VectorLong.normalize();
-                Vector2D directionFingerWrist = directionWristFinger.getInverse();
-                Vector2D directionUpperLower = directionWristFinger.getOrthogonal(palmHand.Side == HandSide.Right);
-                Vector2D directionLowerUpper = directionUpperLower.getInverse();
-
-                //handLength
-                Vector2D handLength = 1.5f * thumbDefect.VectorLong;
-
-                //fingersUpper
-                Vector2D fingersUpper = thumbDefect.OuterLong;
-                bool handBelow = true;
-                while (handBelow && fingersUpper.isInBound())
+                if (hand.Fingers.Count == 1)
                 {
-                    fingersUpper += directionWristFinger;
-                    Vector2D below = fingersUpper.copy();
-                    bool handBelowFound = false;
-                    while (!handBelowFound && below.getDistanceTo(fingersUpper) < 2 * Parameters.FingerMaxWidth && below.isInBound())
+                    List<ConvexityDefect> convexityDefects = findConvexityDefects(hand);
+                    ConvexityDefect thumbDefect = findThumbDefect(hand.Fingers[0], convexityDefects);
+                    if (thumbDefect != null)
                     {
-                        handBelowFound = palmHand.isInside(below);
-                        below += directionUpperLower;
+                        Palm palm = createPalm(hand, thumbDefect);
+                        Palms.Add(palm);
                     }
-                    handBelow = handBelowFound;
                 }
+            }
+        }
 
-                //wristUpper
-                Vector2D wristUpper = thumbDefect.Inner + 5 * directionFingerWrist;
-                while (wristUpper.isInBound() && palmHand.isInside(wristUpper))
-                    wristUpper += directionFingerWrist;
-
-                //handWidth
-                Vector2D handWidth = getHandWidth(palmHand, directionUpperLower);
+        private List<ConvexityDefect> findConvexityDefects(Hand hand)
+        {
+            List<ConvexityDefect> convexityDefects;
+            using (MemStorage ms = new MemStorage())
+            {
+                Contour<Point> contour = hand.Mask.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL);
+                List<MCvConvexityDefect> mcvConvexityDefects = new List<MCvConvexityDefect>(contour.GetConvexityDefacts(ms, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE));
 
-                //wristLower
-                Vector2D wristLower = wristUpper + handWidth;
+                convexityDefects = new List<ConvexityDefect>();
+                foreach (MCvConvexityDefect defect in mcvConvexityDefects)
+                    convexityDefects.Add(new ConvexityDefect(defect));
+            }
+            return convexityDefects;
+        }
 
-                //fingersLower
-                Vector2D fingersLower = wristLower + 0.75f * handLength - 0.25f * handWidth;
+        private ConvexityDefect findThumbDefect(Finger thumb, List<ConvexityDefect> convexityDefects)
+        {
+            convexityDefects.Sort((cd1, cd2) => (cd2.Depth.CompareTo(cd1.Depth)));
+            foreach (ConvexityDefect defect in convexityDefects)
+            {
+                if (defect.isPossibleThumbDefect(thumb))
+                    return defect;
+            }
+            return null;
+        }
 
+        private Palm createPalm(Hand hand, ConvexityDefect thumbDefect)
+        {
+            HandSide side = determineHandSide(thumbDefect);
+            Vector2D wristUpper = findWristUpper(hand, thumbDefect);
+            Vector2D fingersUpper = findFingersUpper(hand, thumbDefect, side);
+            float palmWidth = findPalmWidth(hand, thumbDefect, side);
+            float palmLength = wristUpper.getDistanceTo(fingersUpper);
+            Vector2D directionWristFingers = thumbDefect.VectorLong.normalize();
+            Vector2D directionUpperLower = thumbDefect.VectorLong.getOrthogonal(side == HandSide.Right).normalize();
+            Vector2D wristLower = wristUpper.moveWithinBound(directionUpperLower, palmWidth);
+            Vector2D fingersLower = (wristUpper + 0.75f * palmLength * directionWristFingers + 0.75f * palmWidth * directionUpperLower).moveInBound((directionUpperLower + directionWristFingers).normalize());
+
+            return new Palm(hand, thumbDefect, side, wristUpper, fingersUpper, fingersLower, wristLower);
+        }
 
-                Palm palm = new Palm(palmHand, wristUpper, wristLower, fingersLower, fingersUpper);
-                Palms.Add(palm);
+        private HandSide determineHandSide(ConvexityDefect thumbDefect)
+        {
+            if (thumbDefect.VectorShort.crossProduct(thumbDefect.VectorLong) < 0)
+                return HandSide.Right;
+            else
+                return HandSide.Left;
+        }
 
+        private Vector2D findWristUpper(Hand hand, ConvexityDefect thumbDefect)
+        {
+            Vector2D wristDirection = thumbDefect.VectorLong.getInverse().normalize();
+            Vector2D wristUpper = thumbDefect.Inner.moveWithinBound(wristDirection, 5f);
+            Vector2D wristUpperNext = wristUpper + wristDirection;
+            while (wristUpperNext.isInBound() && hand.isInside(wristUpperNext))
+            {
+                wristUpper = wristUpperNext;
+                wristUpperNext += wristDirection;
             }
+            return wristUpper;
         }
 
-        private Vector2D getHandWidth(Hand palmHand, Vector2D directionUpperLower)
+        private Vector2D findFingersUpper(Hand hand, ConvexityDefect thumbDefect, HandSide side)
         {
-            Vector2D lineStart = palmHand.ThumbDefect.Inner;
-            Vector2D lineEnd = palmHand.ThumbDefect.OuterLong;
-            Vector2D step = (lineEnd - lineStart) / Parameters.PalmNumPositionsForHandWidth;
-            Vector2D currentStart = lineStart;
+            Vector2D fingersDirection = thumbDefect.VectorLong.normalize();
+            Vector2D lowerDirection = fingersDirection.getOrthogonal(side == HandSide.Right).normalize();
+            Vector2D fingersUpper = thumbDefect.OuterLong;
+            Vector2D fingersUpperNext = fingersUpper + fingersDirection;
+            bool handBelow = true;
+            while (handBelow && fingersUpperNext.isInBound())
+            {
+                fingersUpper = fingersUpperNext;
+                fingersUpperNext += fingersDirection;
+                Vector2D below = fingersUpper.copy();
+                handBelow = false;
+                int distance = 0;
+                while (!handBelow && distance < Parameters.FingerMaxWidth && below.isInBound())
+                {
+                    handBelow = hand.isInside(below);
+                    below += lowerDirection;
+                }
+            }
+            return fingersUpper;
+        }
 
-            Vector2D maxWidth = null;
-            float maxWidthLength = float.MinValue;
+        private float findPalmWidth(Hand hand, ConvexityDefect thumbDefect, HandSide side)
+        {
+            Vector2D lowerDirection = thumbDefect.VectorLong.getOrthogonal(side == HandSide.Right).normalize();
+            Vector2D current = thumbDefect.Inner;
+            Vector2D step = thumbDefect.VectorLong / Parameters.PalmNumPositionsForPalmWidth;
 
-            for (int i = 0; i < Parameters.PalmNumPositionsForHandWidth; i++)
+            float maxWidth = float.MinValue;
+            for (int i = 0; i < Parameters.PalmNumPositionsForPalmWidth; i++)
             {
-                Vector2D lower = currentStart + 10 * directionUpperLower;
-                while (lower.isInBound() && palmHand.isInside(lower))
-                    lower += directionUpperLower;
-                Vector2D width = (lower - currentStart);
-                float length = width.Length;
-                if (length > maxWidthLength)
+                Vector2D lower = current.moveWithinBound(lowerDirection, 10f);
+                float width = current.getDistanceTo(lower);
+                while (lower.isInBound() && hand.isInside(lower))
                 {
-                    maxWidth = width;
-                    maxWidthLength = length;
+                    lower += lowerDirection;
+                    width += 1;
                 }
-                currentStart += step;
+                maxWidth = Math.Max(maxWidth, width);
+                current += step;
             }
             return maxWidth;
         }

+ 7 - 4
bbiwarg/Recognition/PalmRecognition/PalmTracker.cs

@@ -17,10 +17,13 @@ namespace bbiwarg.Recognition.PalmRecognition
             return new TrackedPalm(idPool.getNextUnusedID(), detectedPalm, Parameters.PalmTrackerNumFramesDetectedUntilTracked, Parameters.PalmTrackerNumFramesLostUntilDeleted);
         }
 
-        private List<Palm> getOptimizedPalms() {
-            List<Palm> optimizedPalms = new List<Palm>(); 
-            foreach(TrackedPalm tp in TrackedObjects) {
-                optimizedPalms.Add(tp.OptimizedPalm);
+        private List<Palm> getOptimizedPalms()
+        {
+            List<Palm> optimizedPalms = new List<Palm>();
+            foreach (TrackedPalm tp in TrackedObjects)
+            {
+                if (tp.CurrentState == TrackingState.Tracked)
+                    optimizedPalms.Add(tp.OptimizedPalm);
             }
             return optimizedPalms;
         }

+ 5 - 4
bbiwarg/Recognition/PalmRecognition/TrackedPalm.cs

@@ -34,7 +34,7 @@ namespace bbiwarg.Recognition.PalmRecognition
             fingersUpperKalman.setInitialPosition(detectedPalm.FingersUpper);
             fingersLowerKalman.setInitialPosition(detectedPalm.FingersLower);
 
-            updateOptimizedPalm();
+            updateOptimizedPalm(detectedPalm);
             logStateChange();
         }
 
@@ -52,12 +52,13 @@ namespace bbiwarg.Recognition.PalmRecognition
                 fingersUpperKalman.getCorrectedPosition(detectedPalm.FingersUpper);
                 fingersLowerKalman.getCorrectedPosition(detectedPalm.FingersLower);
 
-                updateOptimizedPalm();
+                updateOptimizedPalm(detectedPalm);
             }
         }
 
-        private void updateOptimizedPalm() {
-            OptimizedPalm = new Palm(LastObject.Hand, WristUpperPrediction, WristLowerPrediction, FingersLowerPrediction, FingersUpperPrediction);
+        private void updateOptimizedPalm(Palm detectedPalm)
+        {
+            OptimizedPalm = new Palm(detectedPalm.Hand, detectedPalm.ThumbDefect, detectedPalm.HandSide, WristUpperPrediction, FingersUpperPrediction, FingersLowerPrediction, WristLowerPrediction);
         }
 
         public override float calculateSimilarity(Palm detectedPalm)

+ 2 - 1
bbiwarg/Recognition/TouchRecognition/TouchDetector.cs

@@ -33,7 +33,8 @@ namespace bbiwarg.Recognition.TouchRecognition
                 detectTouch();
         }
 
-        private void detectTouch() {
+        private void detectTouch()
+        {
             foreach (Finger finger in fingers)
             {
                 Vector2D tipPoint = finger.TipPoint;

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

@@ -10,7 +10,8 @@ namespace bbiwarg.Recognition.Tracking
     {
         public int TrackID { get; private set; }
 
-        public void setTracked(int id) {
+        public void setTracked(int id)
+        {
             TrackID = id;
         }
     }

+ 0 - 1
bbiwarg/Utility/Quadrangle.cs

@@ -15,7 +15,6 @@ namespace bbiwarg.Utility
 {
     class Quadrangle
     {
-        public Vector2D[] Vertices { get { return new Vector2D[4] { TopLeft, TopRight, BottomRight, BottomLeft }; } }
         public Vector2D TopLeft { get; private set; }
         public Vector2D TopRight { get; private set; }
         public Vector2D BottomRight { get; private set; }

+ 3 - 1
bbiwarg/bbiwarg.csproj

@@ -96,9 +96,11 @@
     <Compile Include="Recognition\HandRecognition\Hand.cs" />
     <Compile Include="Recognition\HandRecognition\HandDetector.cs" />
     <Compile Include="Recognition\HandRecognition\HandTracker.cs" />
-    <Compile Include="Recognition\HandRecognition\TrackedHand.cs" />
     <Compile Include="Recognition\PalmRecognition\Palm.cs" />
     <Compile Include="Recognition\PalmRecognition\PalmDetector.cs" />
+    <Compile Include="Recognition\HandRecognition\TrackedHand.cs" />
+    <Compile Include="Recognition\PalmRecognition\OldPalm.cs" />
+    <Compile Include="Recognition\PalmRecognition\OldPalmDetector.cs" />
     <Compile Include="Recognition\PalmRecognition\PalmTracker.cs" />
     <Compile Include="Recognition\PalmRecognition\TrackedPalm.cs" />
     <Compile Include="Recognition\TouchRecognition\TouchDetector.cs" />