using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using Emgu.CV; using Emgu.CV.Structure; using bbiwarg.Recognition.FingerRecognition; using bbiwarg.Utility; using bbiwarg.Recognition.Tracking; using bbiwarg.Recognition.PalmRecognition; namespace bbiwarg.Recognition.HandRecognition { class Hand : TrackableObject { public Vector2D Centroid { get; private set; } public Image Mask { get; private set; } public List Fingers { get; private set; } public Palm Palm { get; set; } public Hand(Image mask, List fingers) { Mask = mask; Fingers = fingers; foreach (Finger finger in Fingers) finger.Hand = this; } public bool isInside(Vector2D point) { return (Mask.Data[point.IntY, point.IntX, 0] != 0); } public void mergeWith(Hand mergeHand) { extendMask(mergeHand.Mask); Fingers.AddRange(mergeHand.Fingers); foreach (Finger finger in mergeHand.Fingers) finger.Hand = this; } public void extendMask(Image extendMask) { Mask = Mask.Or(extendMask); } public void fillOverlappingFingers(List otherFingers) { foreach (Finger finger in otherFingers) { FingerSliceTrail trail = null; foreach (FingerSlice slice in finger.SliceTrail.Slices) { Vector2D out1 = slice.Start.moveWithinBound(slice.Direction.getInverse(), Parameters.FingerContourMargin); Vector2D out2 = slice.End.moveWithinBound(slice.Direction, Parameters.FingerContourMargin); if (isInside(out1) && isInside(out2)) { if (trail == null) trail = new FingerSliceTrail(slice); else trail.addSlice(slice); } } if (trail != null) Mask.FillConvexPoly(trail.getContour(Parameters.FingerOutMargin).ToArray(), new Gray(1)); } Mask = Mask.Dilate(1); } public void findCentroid() { MCvPoint2D64f gravityCenter = Mask.GetMoments(true).GravityCenter; Centroid = new Vector2D((float)gravityCenter.x, (float)gravityCenter.y); } } }