private void CreateBitMapFromDepthFrame(DepthImageFrame frame)
        {
            if (frame != null)
            {
                // get image from frame
                short[] depthPixels = new short[frame.PixelDataLength];
                short[] secondDepthPixels = new short[frame.PixelDataLength];
                frame.CopyPixelDataTo(depthPixels);
                Array.Copy(depthPixels, secondDepthPixels, frame.PixelDataLength);
                // find closest point in depth frame (in millimeters)

                this.rawDepthFrame = new DepthFrame() { Pixels = depthPixels, Height = frame.Height, Width = frame.Width};
                this.croppedFrame = this.floodFill.Process(depthPixels, frame.Height, frame.Width);
                this.sensor.DepthStream.Range = this.floodFill.ClosestDistance < 1000 ? DepthRange.Near : DepthRange.Default;
                
                if (this.FrameReady != null)
                {
                    this.FrameReady(this, new DepthFrameEventArgs()
                    {
                        Frame = this.croppedFrame
                    });
                }

                switch (this.mode)
                {
                    case ProgramMode.Classifying:
                        this.Classify();
                        break;
                    case ProgramMode.Learning:
                        this.Train();
                        break;
                }
            }
        }
        public void ClassifyImage(DepthFrame croppedFrame)
        {
            double ratio = ((double)croppedFrame.Width) / (croppedFrame.Width + croppedFrame.Height);
            // Ignore too big/small cropped images and broken case.
            if (croppedFrame.Width < 200 && croppedFrame.Height < 200 && croppedFrame.Width >= 10 && croppedFrame.Height >= 10 && ratio > 0.2 && ratio < 0.8)
            {
                short[,] imageData = MatrixUtil.RawFrameTo2D(croppedFrame.Pixels, croppedFrame.Height, croppedFrame.Width);

                // queue classifer
                if (!this.classifying)
                {
                    this.classifying = true;
                    ThreadPool.QueueUserWorkItem(new WaitCallback(Classify), imageData);
                }
            }
            else
            {
                // too big
                this.category = 0;
                if (this.CategoryDetected != null)
                {
                    this.CategoryDetected(this, new CategoryEventArgs() { CategoryLabel = this.category });
                }
            }
        }
        public void LearnGesture(DepthFrame croppedFrame)
        {
            if (croppedFrame.Width < 200 && croppedFrame.Height < 200 && croppedFrame.Width > 50 && croppedFrame.Height > 50)
            {
                short[,] imageData = MatrixUtil.RawFrameTo2D(croppedFrame.Pixels, croppedFrame.Height, croppedFrame.Width);

                // queue trainer
                if (!this.learning && !this.GestureDataReady)
                {
                    this.learning = true;
                    ThreadPool.QueueUserWorkItem((state) =>
                    {
                        this.Learn(imageData);
                    });
                }
            }
        }