using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using bbiwarg.Images; using bbiwarg.Detectors.FingerDetection; using bbiwarg.Graphics; using bbiwarg.Utility; using Emgu.CV; using Emgu.CV.Structure; namespace bbiwarg.Detectors.HandDetection { class HandDetector { private DepthImage depthImage; private EdgeImage edgeImage; private List fingers; public List Hands { get; private set; } public OutputImage outputImage; public HandDetector(DepthImage depthImage, EdgeImage edgeImage, List fingers, OutputImage outputImage) { this.depthImage = depthImage; this.edgeImage = edgeImage; this.fingers = fingers; this.outputImage = outputImage; detectHands(); drawHands(); } private void detectHands() { int width = depthImage.Width; int height = depthImage.Height; int maxArea = width * height; Image image = edgeImage.Image.Copy().Dilate(2).Erode(2).Mul(255); //draw top finger slice foreach (Finger finger in fingers) { // TODO: connect contour with other edges //Contour contour = finger.getContour(); //image.FillConvexPoly(contour.ToArray(), new Gray(0)); //image.DrawPolyline(finger.getContour().ToArray(), false, new Gray(255), 1); FingerSlice slice = finger.SliceTrail.Slices[1]; image.Draw(new Emgu.CV.Structure.LineSegment2D(slice.Start, slice.End), new Gray(255), 2); } Hands = new List(); foreach (Finger finger in fingers) { bool newHand = true; foreach (Hand hand in Hands) { if (hand.isInside(finger.HandPoint)) { hand.addFinger(finger); newHand = false; } } if (newHand) { Image mask = new Image(width + 2, height + 2); MCvConnectedComp comp = new MCvConnectedComp(); CvInvoke.cvFloodFill(image, finger.HandPoint, new MCvScalar(255), new MCvScalar(1), new MCvScalar(1), out comp, Emgu.CV.CvEnum.CONNECTIVITY.FOUR_CONNECTED, Emgu.CV.CvEnum.FLOODFILL_FLAG.DEFAULT, mask); if (comp.area < maxArea * Constants.HandMaxSize) { Hand hand = new Hand(mask.Copy(new Rectangle(1, 1, width, height))); hand.addFinger(finger); Hands.Add(hand); } } } } private void drawHands() { int maxIndex = Math.Min(3, Hands.Count); for (int i = 0; i < maxIndex ; i++) { outputImage.Image[i] = Hands[i].Mask.Mul(255); } } } }