2. Converting depth data to 3d coordinates

This code gets depth data and converts it to a 3d coordinates a.k.a SkeletonPoints. Using this 3D data, a virtual box or viewport is created which limits the area the camera detects objects. Distances for SkeletonPoints are measured in meters.

Download this Visual Studio project

Here’s the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using Microsoft.Kinect;
using KinectMouseController;

namespace WpfApp1
{

    public partial class MainWindow : Window
    {

        KinectSensor sensor;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void loaded(object sender, RoutedEventArgs e)
        {
            if(KinectSensor.KinectSensors.Count > 0)
            {
                sensor = KinectSensor.KinectSensors[0];
                
                if(sensor.Status == KinectStatus.Connected)
                {
                    sensor.ColorStream.Enable();
                    sensor.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);
                    sensor.SkeletonStream.Enable();
                    sensor.AllFramesReady += Sensor_AllFramesReady;
                    sensor.Start();
                }
            }
        }

        private void Sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
        {
            using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
            {
                if(depthFrame == null)
                {
                    return;
                }

                byte[] pixels = GenerateColouredBytes(depthFrame);
                int stride = depthFrame.Width * 4;
                image1.Source = BitmapSource.Create(depthFrame.Width, depthFrame.Height, 96, 96, PixelFormats.Bgr32, null, pixels, stride);
            }
        }
        
        private byte[] GenerateColouredBytes(DepthImageFrame depthFrame)
        {
            DepthImagePixel[] rawDepthData = new DepthImagePixel[depthFrame.PixelDataLength];
            depthFrame.CopyDepthImagePixelDataTo(rawDepthData);

            SkeletonPoint[] skelectonPoints = new SkeletonPoint[rawDepthData.Length];
            CoordinateMapper cm = new CoordinateMapper(sensor);
            cm.MapDepthFrameToSkeletonFrame(DepthImageFormat.Resolution320x240Fps30, rawDepthData, skelectonPoints);

            byte[] colourPixels = new byte[depthFrame.Height * depthFrame.Width * 4];
            const int BlueIndex = 0;
            const int GreenIndex = 1;
            const int RedIndex = 2;

            for(int depthIndex = 0, colorIndex = 0;
                depthIndex < rawDepthData.Length && colorIndex < colourPixels.Length;
                depthIndex++, colorIndex+=4)
            {
                float x = skelectonPoints[depthIndex].X * 100;
                float y = skelectonPoints[depthIndex].Y * 100;
                float z = skelectonPoints[depthIndex].Z * 100;

                if (-10 < x && x < 10 && 50 < z && z < 100)
                {
                    colourPixels[colorIndex + BlueIndex] = (byte) 0;
                    colourPixels[colorIndex + GreenIndex] = (byte) 0;
                    colourPixels[colorIndex + RedIndex] = (byte) z;
                }
                else
                {
                    colourPixels[colorIndex + BlueIndex] = (byte) 255;
                    colourPixels[colorIndex + GreenIndex] = (byte) 255;
                    colourPixels[colorIndex + RedIndex] = (byte) 255;
                }
            }

            return colourPixels;
        }

        private void closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            sensor.Stop();
            sensor.AudioSource.Stop();
        }
    }
}