using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using bbiwarg.Recognition.HandRecognition; using bbiwarg.Utility; using Emgu.CV.Structure; using Emgu.CV; namespace bbiwarg.Recognition.PalmRecognition { class PalmDetector { private List hands; private List palmHands; public List Palms { get; private set; } public PalmDetector(List hands) { this.hands = hands; findPalmHands(); createPalms(); } private void findPalmHands() { palmHands = new List(); foreach (Hand hand in hands) { if (hand.ThumbDefect != null) palmHands.Add(hand); } } private void createPalms() { Palms = new List(); foreach (Hand palmHand in palmHands) { ConvexityDefect thumbDefect = palmHand.ThumbDefect; /* Vector2D handLength = 1.5f * thumbDefect.VectorLong; Vector2D handWidth = 0.45f * handLength.getOrthogonal(palmHand.Side == HandSide.Right); Vector2D fingersUpperOld = thumbDefect.Inner + 0.8f * handLength; Vector2D wristUpperOld = thumbDefect.Inner - 0.2f * handLength; Vector2D wristLowerOld = wristUpperOld + handWidth; Vector2D fingersLowerOld = wristLowerOld + 0.75f * handLength - 0.3f * handWidth; */ 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()) { fingersUpper += directionWristFinger; Vector2D below = fingersUpper.copy(); bool handBelowFound = false; while (!handBelowFound && below.getDistanceTo(fingersUpper) < 2*Parameters.FingerMaxWidth && below.isInBound()) { below += directionUpperLower; handBelowFound = palmHand.isInside(below); } handBelow = handBelowFound; } //wristUpper Vector2D wristUpper = thumbDefect.Inner; while (wristUpper.isInBound() && palmHand.isInside(wristUpper)) wristUpper += directionFingerWrist; //handWidth Vector2D lower = thumbDefect.Inner + 10 * directionUpperLower; while (lower.isInBound() && palmHand.isInside(lower)) lower += directionUpperLower; Vector2D handWidth = (lower - thumbDefect.Inner); //wristLower Vector2D wristLower = wristUpper + handWidth; //fingersLower Vector2D fingersLower = wristLower + 0.75f * handLength - 0.25f * handWidth; Palm palm = new Palm(palmHand, wristUpper, wristLower, fingersLower, fingersUpper); Palms.Add(palm); palmHand.setPalm(palm); } } } }