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();
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。