將深度圖像數據轉換爲彩色數據

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 Microsoft.Kinect;數組

namespace DepthViewer
{
/// 函數


/// MainWindow.xaml 的交互邏輯
///

public partial class MainWindow : Window
{
KinectSensor kinectSensor;//表明一個單獨的Kinect設備,若是連入多個Kinect可定義一個數組
private short[] pixelData;//short數組用來存放獲取到的深度圖像數據。深度圖像數據中的每一個像素都是用16位表示的,所以用short數組。
byte[] depthFrame32;//用來存儲彩色圖像數據
private const int RedIndex = 2;
private const int GreenIndex = 1;
private const int BlueIndex = 0;
public MainWindow()
{
InitializeComponent();
}

/// <summary>
    /// 將獲得的原始灰度深度數據轉化爲彩色數據
    /// </summary>
    /// <param name="depthFrame"></param>
    /// <param name="depthStreame"></param>
    /// <returns></returns>
    private byte[] ConverDepthFrame(short[] depthFrame, DepthImageStream depthStreame)
    {
        int tooNearDepth = depthStreame.TooNearDepth;
        int tooFarDepth = depthStreame.TooFarDepth;
        int unknownDepth = depthStreame.UnknownDepth;

        for(int i = 0,j = 0; i <depthFrame.Length && j < this.depthFrame32.Length;i++,j +=4)
        {
            int player = depthFrame[i] & DepthImageFrame.PlayerIndexBitmask;
            int realDepth = depthFrame[i] >> DepthImageFrame.PlayerIndexBitmaskWidth;
            //根據深度值的不一樣着以不一樣的顏色
            if(player == 0 && realDepth ==0)
            {
                this.depthFrame32[j + RedIndex] = 255;
                this.depthFrame32[j + GreenIndex] = 255;
                this.depthFrame32[j + BlueIndex] = 255;
            }
            else if(player == 0&& realDepth > 0 && realDepth <= tooFarDepth)
            {
                this.depthFrame32[j + RedIndex] = 0;
                this.depthFrame32[j + GreenIndex] = 255;
                this.depthFrame32[j + BlueIndex] = 255;
            }
            else if(player == 0&& realDepth > tooNearDepth && realDepth < tooFarDepth)
            {
                this.depthFrame32[j + RedIndex] = 160;
                this.depthFrame32[j + GreenIndex] = 32;
                this.depthFrame32[j + BlueIndex] = 240;
            }
            else if(player ==0 && realDepth >= tooFarDepth)
            {
                this.depthFrame32[j + RedIndex] = 192;
                this.depthFrame32[j + GreenIndex] = 192;
                this.depthFrame32[j + BlueIndex] = 192;
            }
            else if(player == 0 && realDepth == unknownDepth)
            {
                this.depthFrame32[j + RedIndex] = 255;
                this.depthFrame32[j + GreenIndex] = 255;
                this.depthFrame32[j + BlueIndex] = 0;
            }
            else if(player > 0)
            {
                switch (player)
                {
                    case 1:
                        this.depthFrame32[j + RedIndex] = 255;
                        this.depthFrame32[j + GreenIndex] = 0;
                        this.depthFrame32[j + BlueIndex] = 0;
                        break;
                    case 2:
                        this.depthFrame32[j + RedIndex] = 0;
                        this.depthFrame32[j + GreenIndex] = 255;
                        this.depthFrame32[j + BlueIndex] = 0;
                        break;
                    default:
                        this.depthFrame32[j + RedIndex] = 0;
                        this.depthFrame32[j + GreenIndex] = 0;
                        this.depthFrame32[j + BlueIndex] = 255;
                        break;
                }
            }
        }
        return this.depthFrame32;
    }
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        //首先使用LINQ語句篩選鏈接到電腦的Kinect設備,並賦值給kinectSensor。
        kinectSensor = (from sensor in KinectSensor.KinectSensors where sensor.Status == KinectStatus.Connected select sensor).FirstOrDefault();
        //而後調用DepthStream的Enable()函數啓用深度圖像數據,其參數爲Resolution320x240Fps30,含義是設置深度圖像的分辨率爲320X240,幀率爲30f/s。
        kinectSensor.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);
        //調用start()函數啓動Kinect數據流。
        kinectSensor.Start();
        //每當下一幀的深度圖像數據準備好時,DepthFrameReady事件會通知應用程序添加一個kinectSensor_DepthFrameReady事件處理函數,以獲取該事件返回的通知,參數類型爲DepthImageFrameReadyEventArgs。
        kinectSensor.DepthFrameReady += new EventHandler<DepthImageFrameReadyEventArgs>(kinectSensor_DepthFrameReady);
    }

    private void kinectSensor_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
    {
        using (DepthImageFrame depthImageFrame = e.OpenDepthImageFrame())//調用OpenDepthImageFrame()函數獲取深度圖像數據,數據類型定義爲DepthImageFrame。
        {
            if (depthImageFrame != null)//depthImageFrame不爲空表明獲取到了深度圖像數據
            {
                //調用DepthImageFrame的CopyPixelDataTo()方法,將從Kinect設備獲取到的深度圖像數據複製到short數組
                pixelData = new short[depthImageFrame.PixelDataLength];//給pixelData分配相應的空間,大小由depthImageFrame的PixelDataLength屬性決定
                depthImageFrame.CopyPixelDataTo(pixelData);


                this.depthFrame32 = new byte[depthImageFrame.Width * depthImageFrame.Height * 4];
                this.depthFrame32 = ConverDepthFrame(pixelData, ((KinectSensor)sender).DepthStream);//對ConverDepthFrame的調用
                /*利用獲取到的數據建立一個BitmapSource,並將其賦值發給最初添加的Image控件ColorImage的Source屬性。
                 * 這樣就能夠不斷的將獲取到的下一幀的深度圖像數據刷新顯示到界面上
                 */
                this.DepthImage.Source = BitmapSource.Create(depthImageFrame.Width,
                    //像素格式PixelFormats的值爲Gray16,原始的深度圖像數據是16位灰度圖像
                    depthImageFrame.Height, 96, 96, PixelFormats.Gray16, null, pixelData,
                    depthImageFrame.Width * depthImageFrame.BytesPerPixel);
            }

        }
    }

    private void Window_Closed(object sender, EventArgs e)
    {
        kinectSensor.Stop();
    }

}

}this

相關文章
相關標籤/搜索