using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; using Emgu.CV; using Emgu.CV.Structure; using bbiwarg.Images; namespace bbiwarg.Detectors.Fingers { class FingerDetector { private DepthImage depthImage; private EdgeImage edgeImage; private FingerImage fingerImage; private List possibleFingers; private List fingers; public FingerDetector(DepthImage depthImage, EdgeImage edgeImage, FingerImage fingerImage) { this.depthImage = depthImage; this.edgeImage = edgeImage; this.fingerImage = fingerImage; findPossibleFingerPoints(); findPossibleFingers(); setFingers(); setFingerPoints(); } public List getFingers() { return fingers; } private void findPossibleFingerPoints() { int width = depthImage.getWidth(); int height = depthImage.getHeight(); int maxFingerSize = 30; int minFingerSize = 10; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (edgeImage.isEdgeAt(x,y)) { //search horizontal bool edgeRightFound = false; int edgeRightX = x + minFingerSize; while (!edgeRightFound && edgeRightX < width) { if (edgeImage.isEdgeAt(edgeRightX,y)) edgeRightFound = true; else edgeRightX++; } if (edgeRightFound){ int midX = (edgeRightX + x) / 2; Int16 depthLeft = depthImage.getDepthAt(x, y); Int16 depthMid = depthImage.getDepthAt(midX, y); Int16 depthRight = depthImage.getDepthAt(edgeRightX, y); if ((edgeRightX - x) < maxFingerSize && depthLeft > depthMid && depthMid < depthRight) { fingerImage.setFingerAt(midX, y, FingerImageState.possibleFinger); } } //search vertical bool edgeBottomFound = false; int edgeBottomY = y + minFingerSize; while (!edgeBottomFound && edgeBottomY < height) { if (edgeImage.isEdgeAt(x, edgeBottomY)) edgeBottomFound = true; else edgeBottomY++; } if (edgeBottomFound) { int midY = (edgeBottomY + y) / 2; Int16 depthTop = depthImage.getDepthAt(x, y); Int16 depthMid = depthImage.getDepthAt(x, midY); Int16 depthBottom = depthImage.getDepthAt(x, edgeBottomY); if ((edgeBottomY - y) < maxFingerSize && depthTop > depthMid && depthMid < depthBottom) { fingerImage.setFingerAt(x, midY, FingerImageState.possibleFinger); } } } } } } private void findPossibleFingers() { int width = depthImage.getWidth(); int height = depthImage.getHeight(); float maxDistanceTogether = 5.0f; possibleFingers = new List(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (fingerImage.getStateAt(x,y) == FingerImageState.possibleFinger) { Int16 depth = depthImage.getDepthAt(x, y); FingerPoint fingerPoint = new FingerPoint(x,y,depth); float minDistanceValue = float.MaxValue; int minDistanceIndex = 0; for (int i = 0; i < possibleFingers.Count; i++) { float distance = possibleFingers[i].getMinDistance(fingerPoint); if (distance < minDistanceValue) { minDistanceValue = distance; minDistanceIndex = i; } } if (minDistanceValue < maxDistanceTogether) { possibleFingers[minDistanceIndex].addFingerPoint(fingerPoint); } else { possibleFingers.Add(new Finger(fingerPoint)); } } } } } private void setFingers() { int width = depthImage.getWidth(); int height = depthImage.getHeight(); float minFingerLength = 20.0f; fingers = new List(); foreach (Finger finger in possibleFingers) { float length = finger.getLength(); if (length > minFingerLength) { fingers.Add(finger); } } } private void setFingerPoints() { int width = depthImage.getWidth(); int height = depthImage.getHeight(); foreach (Finger finger in fingers) { PointF lineEndPoint1 = finger.getLineEndPoint1(); PointF lineEndPoint2 = finger.getLineEndPoint2(); fingerImage.drawLine(lineEndPoint1, lineEndPoint2, FingerImageState.fingerDetected); } } } }