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.Images; using bbiwarg.Detectors.Fingers; using bbiwarg.Utility; namespace bbiwarg.Detectors.Touch { class TouchDetector { private DepthImage depthImage; private TouchImage touchImage; private List fingers; private List touchEvents; public TouchDetector(List fingers, DepthImage depthImage, TouchImage touchImage) { this.depthImage = depthImage; this.touchImage = touchImage; this.fingers = fingers; this.touchEvents = new List(); float floodValueThreshold = 0.5f; foreach (Finger finger in fingers) { Vector tipPoint = finger.getTipPoint(); float floodValue = getFloodValue(tipPoint.x, tipPoint.y); if (floodValue > floodValueThreshold) { //correct touchEvent position Vector direction = finger.getDirection(); float directionFactor = -10; float x = Math.Min(Math.Max(tipPoint.x + directionFactor * direction.x, 0), depthImage.getWidth()); float y = Math.Min(Math.Max(tipPoint.y + directionFactor * direction.y, 0), depthImage.getHeight()); Vector tep = new Vector(new float[2]{x,y}); touchImage.setTouchAt((int)tep.x, (int)tep.y, TouchImageState.touchDetected); TouchEvent touchEvent = new TouchEvent((int)tep.x, (int)tep.y, floodValue, finger); touchEvents.Add(touchEvent); } } } public List getTouchEvents() { return touchEvents; } private float getFloodValue(int touchX, int touchY) { int searchSize = 15; int maxDepthDifference = 20; Int16 fingerDiameter = 7; Int16 depthAtTouch = (Int16) (depthImage.getDepthAt(touchX, touchY) + fingerDiameter); int minX = Math.Max(touchX - searchSize, 0); int maxX = Math.Min(touchX + searchSize, depthImage.getWidth()); int minY = Math.Max(touchY - searchSize, 0); int maxY = Math.Min(touchY + searchSize, depthImage.getHeight()); int matchedPixels = 0; int countedPixels = 0; for (int x = minX; x < maxX; x++) { for (int y = minY; y < maxY; y++) { Int16 depth = depthImage.getDepthAt(x,y); touchImage.setTouchAt(x, y, TouchImageState.touchArea); if (Math.Abs(depthAtTouch - depth) < maxDepthDifference) { matchedPixels++; touchImage.setTouchAt(x, y, TouchImageState.touchAreaMatched); } countedPixels++; } } float rel = (float)matchedPixels / (float)countedPixels; //status bar (% of matched pixels) -> green for (int x = minX; x < minX + (maxX-minX)*rel; x++) { touchImage.setTouchAt(x, maxY - 1, TouchImageState.touchAreaStatusBar); } return rel; } } }