using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Diagnostics; using bbiwarg.Utility; using bbiwarg.Detectors.Fingers; using bbiwarg.Detectors.Palm; using bbiwarg.Detectors.Touch; using bbiwarg.Images; using bbiwarg.InputProviders; using Emgu.CV; using Emgu.CV.Structure; using bbiwarg.Graphics; namespace bbiwarg { class VideoHandle { private IInputProvider inputProvider; private InputFrame inputFrame; public int Width { get; private set; } public int Height { get; private set; } public int CurrentFrame { get { if (sourceIsMovie()) return inputProvider.getCurrentMovieFrame(); else return videoFrame; } } public OutputImage[] OutputImages { get; private set; } private DepthImage depthImage; private EdgeImage edgeImage; private FingerDetector fingerDetector; private PalmDetector palmDetector; private TouchDetector touchDetector; private PalmTouchDetector palmTouchDetector; private FingerTracker fingerTracker; private TouchTracker touchTracker; private TouchEventVisualizer touchEventVisualizer; private int videoFrame = 0; public VideoHandle(IInputProvider inputProvider) { this.inputProvider = inputProvider; //initialize trackers touchTracker = new TouchTracker(); fingerTracker = new FingerTracker(); } public void start() { inputProvider.init(); inputProvider.start(); inputProvider.updateFrame(); processFrameUpdate(); } public void stop() { inputProvider.stop(); } public bool sourceIsMovie() { return inputProvider.sourceIsMovie(); } public void reversePlay() { inputProvider.reversePlay(); } public void pauseMovie() { inputProvider.pauseMovie(); } public void unpauseMovie() { inputProvider.unpauseMovie(); } public void nextFrame() { if (inputProvider.isActive()) { inputProvider.releaseFrame(); inputProvider.updateFrame(); processFrameUpdate(); } else { inputProvider.stop(); } ++videoFrame; } public List getPalmTouchEvents() { return palmTouchDetector.PalmTouchEvents; } private void processFrameUpdate() { Timer.start("processFrameUpdate"); //read data from inputProvider Timer.start("readInputData"); inputFrame = inputProvider.getInputFrame(); Width = inputFrame.Width; Height = inputFrame.Height; Timer.stop("readInputData"); //create output images Timer.start("createOtherImages"); int numImages = 4; OutputImages = new OutputImage[numImages]; for (int i = 0; i < numImages; i++) { OutputImages[i] = new OutputImage(Width, Height); } Timer.stop("createOtherImages"); //create depthImage Timer.start("createDepthImage"); Image image = new Image(Width, Height, Width * 2, inputFrame.RawDepthData); depthImage = new DepthImage(image); Image tmpDepth = (depthImage.MaxDepth - depthImage.MinDepth) - depthImage.Image; OutputImages[0].Image[0] = OutputImages[0].Image[1] = OutputImages[0].Image[2] = tmpDepth; Timer.stop("createDepthImage"); // create edge image Timer.start("createEdgeImage"); edgeImage = new EdgeImage(depthImage); OutputImages[1].Image[2] = edgeImage.Image.ThresholdBinary(new Gray(0), new Gray(1)).Mul(255); Timer.stop("createEdgeImage"); //detect fingers Timer.start("fingerDetection"); fingerDetector = new FingerDetector(depthImage, edgeImage, OutputImages[1]); Timer.stop("fingerDetection"); //track fingers Timer.start("fingerTracking"); fingerTracker.setDetectedTouchEventsThisFrame(fingerDetector.Fingers, OutputImages[1]); Timer.stop("fingerTracking"); //remove background noise Timer.start("removeBackground"); depthImage.removeBackground(fingerTracker.TrackedFingers); edgeImage = new EdgeImage(depthImage); OutputImages[2].Image[0] = OutputImages[2].Image[1] = OutputImages[2].Image[2] = (depthImage.MaxDepth - depthImage.MinDepth) - depthImage.Image; Timer.stop("removeBackground"); //detect palm Timer.start("palmDetection"); palmDetector = new PalmDetector(depthImage, edgeImage, fingerDetector.Fingers, OutputImages[2]); if (sourceIsMovie() && CurrentFrame == 0) PalmDetector.resetFilter(); Timer.stop("palmDetection"); //detect touchEvents Timer.start("touchDetection"); touchDetector = new TouchDetector(fingerTracker.TrackedFingers, depthImage, OutputImages[2]); if (palmDetector.PalmQuad != null) palmTouchDetector = new PalmTouchDetector(touchDetector.TouchEvents, palmDetector.PalmQuad); Timer.stop("touchDetection"); //track touchEvents Timer.start("touchTracking"); touchTracker.setDetectedTouchEventsThisFrame(touchDetector.TouchEvents, OutputImages[2]); Timer.stop("touchTracking"); // touch event visualizer if (touchEventVisualizer == null) touchEventVisualizer = new TouchEventVisualizer(Width, Height); if (CurrentFrame == 0) touchEventVisualizer.Reset(); if (palmTouchDetector != null) { foreach (PalmTouchEvent e in palmTouchDetector.PalmTouchEvents) touchEventVisualizer.addPalmTouchEvent(e, CurrentFrame); touchEventVisualizer.updateImage(); OutputImages[3] = touchEventVisualizer.OutputImage; } // add borders for (int i = 0; i < numImages; i++) { OutputImages[i].drawRectangle(0, 0, Width - 1, Height - 1, Color.White); } Timer.stop("processFrameUpdate"); } } }