public MultiTouchTrackerOmni(NuiSensor sensor)
        {
            this.sensor = sensor;
            sensor.FrameUpdate += new EventHandler<NuiSensor.FrameUpdateEventArgs>(sensor_FrameUpdate);

            width = sensor.DepthGenerator.MapOutputMode.XRes;
            height = sensor.DepthGenerator.MapOutputMode.YRes;

            outputImageSource = new WriteableBitmap(width, height, NuiSensor.DPI_X, NuiSensor.DPI_Y, PixelFormats.Rgb24, null);

            fingersRaw = new int[MAX_FINGERS * 2];
            Fingers = new List<Point3D>(MAX_FINGERS);

            int bufferSize = width * height * 3;
            bufferOutputColored = new byte[bufferSize];

            sensor.CaptureRequested += new EventHandler<NuiSensor.CaptureEventArgs>(sensor_CaptureRequested);

            double realWorldXToZ, realWorldYToZ;
            hackXnConvertProjectiveToRealWorld(out realWorldXToZ, out realWorldYToZ);

            unsafe
            {
                ImageProcessorLib.derivativeFingerDetectorInit(null, null, width, height, width, width * 3, sensor.DepthGenerator.DeviceMaxDepth, realWorldXToZ, realWorldYToZ);
            }
        }
        public void SetSensorVideo(NuiSensor sensor, VideoType videoType)
        {
            this.videoType = videoType;
            this.sensor = sensor;

            Title = videoType.ToString();

            sensor.HandTracker.HandDestroy += new EventHandler<HandDestroyEventArgs>(HandTracker_HandDestroy);
            sensor.HandTracker.HandUpdate += new EventHandler<HandUpdateEventArgs>(HandTracker_HandUpdate);

            refreshWorker = new BackgroundWorker();
            refreshWorker.DoWork += new DoWorkEventHandler(refreshWorker_DoWork);
            CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);

            //create finger points
            for (int i = 0; i < MultiTouchTracker.MAX_FINGERS; i++)
            {
                Ellipse ellipse = new Ellipse()
                {
                    Width = 10,
                    Height = 10,
                    Fill = Brushes.Orange,
                    Stroke = Brushes.White,
                    StrokeThickness = 2,
                    Opacity = 0,
                };
                fingerPoints.Add(ellipse);
                canvas.Children.Add(ellipse);
            }
        }
        public MainWindow()
        {
            InitializeComponent();
            handTrackingControlMap = new Dictionary<int, TrackingDataControl>();

            nuiSensor = new NuiSensor();
            nuiSensor.HandTracker.HandCreate += new EventHandler<OpenNI.HandCreateEventArgs>(HandTracker_HandCreate);
            nuiSensor.HandTracker.HandDestroy += new EventHandler<OpenNI.HandDestroyEventArgs>(HandTracker_HandDestroy);
            nuiSensor.HandTracker.HandUpdate += new EventHandler<OpenNI.HandUpdateEventArgs>(HandTracker_HandUpdate);

            server = new Server(nuiSensor);
            server.Start();
        }
        public MultiTouchTracker(NuiSensor sensor)
        {
            this.sensor = sensor;

            sensor.FrameUpdate += new EventHandler<NuiSensor.FrameUpdateEventArgs>(sensor_FrameUpdate);

            width = sensor.DepthGenerator.MapOutputMode.XRes;
            height = sensor.DepthGenerator.MapOutputMode.YRes;

            bitmap = new WriteableBitmap(width, height, NuiSensor.DPI_X, NuiSensor.DPI_Y, PixelFormats.Rgb24, null);
            resultBitmap = new WriteableBitmap(width, height, NuiSensor.DPI_X, NuiSensor.DPI_Y, PixelFormats.Rgb24, null);

            int bufferSize = width * height;
            bufferSrc = new byte[bufferSize];
            bufferSwitch = new byte[bufferSize];
            bufferDst = new byte[bufferSize];

            fingersRaw = new int[MAX_FINGERS * 2];
            Fingers = new List<Point3D>(MAX_FINGERS);
        }
        void sensor_FrameUpdate(object sender, NuiSensor.FrameUpdateEventArgs e)
        {
            if (CalibrationState == CalibrationState.Requested)
            {
                calibrationStartTime = e.DepthMetaData.Timestamp;
                calibrationMap = new double[e.DepthMetaData.YRes, e.DepthMetaData.XRes];

                unsafe
                {
                    ushort* pDepth = (ushort*)e.DepthMetaData.DepthMapPtr.ToPointer();

                    fixed (double* calibrationMapPtr = calibrationMap)
                    {
                        double* pDest = calibrationMapPtr;
                        for (int i = 0; i < calibrationMap.Length; ++i, ++pDepth, ++pDest)
                        {
                            *pDest = *pDepth;
                        }
                    }
                }

                calibratedFrame = 1;
                CalibrationState = CalibrationState.FirstFrameCaptured;
            }
            else if (CalibrationState == CalibrationState.FirstFrameCaptured)
            {
                unsafe
                {
                    ushort* pDepth = (ushort*)e.DepthMetaData.DepthMapPtr.ToPointer();

                    fixed (double* calibrationMapPtr = calibrationMap)
                    {
                        double* pDest = calibrationMapPtr;
                        for (int i = 0; i < calibrationMap.Length; ++i, ++pDepth, ++pDest)
                        {
                            *pDest = (*pDest * calibratedFrame + *pDepth) / (double)(calibratedFrame + 1);
                        }
                    }
                }

                if (e.DepthMetaData.Timestamp - calibrationStartTime >= calibrationDuration)
                {
                    CalibrationState = CalibrationState.Finished;
                    if (calibrationFinishedHandler != null)
                    {
                        calibrationFinishedHandler();
                    }
                }

                calibratedFrame++;
            }
            else if (CalibrationState == CalibrationState.Finished)
            {
                recognizeFingers(e.DepthMetaData);
            }
        }
        void sensor_FrameUpdate(object sender, NuiSensor.FrameUpdateEventArgs e)
        {
            int fingersNum = 0;
            int[] handHint = new int[4];

            lock (bufferOutputColored)
            {
                unsafe
                {
                    fixed (byte* bufferOutputColorPtr = bufferOutputColored)
                    {
                        fixed (int* fingerRawPtr = fingersRaw, handHintPtr = handHint)
                        {
                            ushort* pDepth = (ushort*)sensor.DepthMetaData.DepthMapPtr.ToPointer();
                            fingersNum = ImageProcessorLib.derivativeFingerDetectorWork(pDepth, bufferOutputColorPtr, width, height, width, width * 3,
                                FingerWidthMin, FingerWidthMax, FingerLengthMin, FingerLengthMax,
                                MAX_FINGERS, fingerRawPtr, handHintPtr);
                        }
                    }
                }
            }

            Fingers.Clear();
            for (int i = 0; i < fingersNum; i++)
            {
                Fingers.Add(new Point3D(fingersRaw[2 * i], fingersRaw[2 * i + 1], 0));
            }

            if (Fingers.Count > 0 && (!sensor.HandTracker.IsTracking || handHint[3] - lastHandDetectConfidence > HAND_CHANGE_CONFIDENCE_THRESHOLD))
            {
                sensor.HandTracker.HandDestroy += new EventHandler<HandDestroyEventArgs>(HandTracker_HandDestroy);
                sensor.HandTracker.StartTrackingAt(new Point3D(handHint[0], handHint[1], handHint[2]));
                lastHandDetectConfidence = handHint[3];
                Trace.WriteLine("Hand hint at " + string.Format("{0}, {1}, {2}", handHint[0], handHint[1], handHint[2]) + " with confidence" + handHint[3].ToString());
            }
        }
        void sensor_CaptureRequested(object sender, NuiSensor.CaptureEventArgs e)
        {
            string fileNameH = e.Folder + e.FileNamePrefix + "derivativeH.csv";
            string fileNameV = e.Folder + e.FileNamePrefix + "derivativeV.csv";
            string fileNameBmp = e.Folder + e.FileNamePrefix + "derivative.bmp";

            StreamWriter swH = new StreamWriter(fileNameH);
            StreamWriter swV = new StreamWriter(fileNameV);

            lock (bufferOutputColored)
            {
                unsafe
                {
                    int* hDerivativeRes, vDerivativeRes;
                    ImageProcessorLib.derivativeFingerDetectorGetDerivativeFrame(&hDerivativeRes, &vDerivativeRes);

                    for (int i = 0; i < height; i++)
                    {
                        for (int j = 0; j < width; j++)
                        {
                            swH.Write(hDerivativeRes[i * width + j].ToString() + ", ");
                            swV.Write(vDerivativeRes[i * width + j].ToString() + ", ");
                        }
                        swH.WriteLine();
                        swV.WriteLine();
                    }
                }
            }

            swH.Close();
            swV.Close();

            BmpBitmapEncoder bmpEncoder = new BmpBitmapEncoder();
            bmpEncoder.Frames.Add(BitmapFrame.Create(outputImageSource));
            FileStream fs = new FileStream(fileNameBmp, FileMode.Create);
            bmpEncoder.Save(fs);
            fs.Close();
        }