创建一个Kincet项目通常需要:

1. 创建一个VS项目,一般为了展示通常创建一个wpf项目。

2. 添加Microsoft.Kinect.dll引用,如果是早期版本的SDK,这个名称可能不同。

3. 引入Kinect命名空间。

Kinect支持3中类型的托管应用程序,分别是:控制台应用程序,WPF以及Windows Form应用程序。


首先来创建一个Windows 控制台应用程序,然后在Main函数所在的代码中引入Kinect命名控件,代码如下:

using Microsoft.Kinect;
static void Main(string[] args)
{
//初始化sensor实例
KinectSensor sensor = KinectSensor.KinectSensors[]; //初始化照相机
sensor.DepthStream.Enable();
sensor.DepthFrameReady += new EventHandler<DepthImageFrameReadyEventArgs>(sensor_DepthFrameReady); // 注册事件,sensor_DepthFrameReady事件函数 Console.ForegroundColor=ConsoleColor.Green; //打开数据流
sensor.Start(); while (Console.ReadKey().Key != ConsoleKey.Spacebar)
{ }
} static void sensor_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
using (var depthFrame=e.OpenDepthImageFrame())
{
if (depthFrame == null) return;
short[] bits = new short[depthFrame.PixelDataLength];
depthFrame.CopyPixelDataTo(bits);
foreach (var bit in bits)
Console.Write(bit);
}
}

基于Kinect开发的应用程序最开始需要用到的对象就是KinectSensor对象,该对象直接表示Kinect硬件设备。KinectSensor对象是我们想要获取数据,包括彩色影像数据,景深数据和骨骼追踪数据的源头。

从KinectSensor获取数据最常用的方式是通过监听该对象的一系列事件。每一种数据流都有对应的事件,当改类型数据流可用时,就会触发改时间。

每一种数据流(Color,Depth,Skeleton)都是以数据点的方式在不同的坐标系中显示的,在后面的讨论中我们能够清楚的看到这一点。将一个数据流中的点数据转换到另一个数据流中是一个很常见的操作,KinectSensor对象有一些列的方法能够进行数据流到数据点阵的转换,他们是MapDepthToColorImagePoint,MapDepthToSkeletonPoint以及MapSkeletonPointToDepth。

1,发现连接的Kinect设备

KinectObject对象没有公共的构造器,应用程序不能直接创建它。相反,该对象是SDK在探测到有连接的Kinect设备时创建的。当有Kinect设备连接到计算机上时,应用程序应该得到通知或者提醒。KinectSeneor对象有一个静态的属性KinectSensors,该属性是一个KinectSensorCollection集合,该集合继承自ReadOnlyCollection,ReadOnlyCollection集合很简单,他只有一个索引器和一个称之为StatusChanged的事件。

只有设备在Connected状态下时,KinectSensor对象才能初始化。在应用的整个生命周期中,传感器的状态可能会发生变化,这意味着我们开发的应用程序必须监控设备的连接状态,并且在设备连接状态发生变化时能够采取相应的措施来提高用户体验。

public partial class MainWindow : Window
{
//私有Kinectsensor对象
private KinectSensor kinect; public KinectSensor Kinect // 为私有变量提供存取接口
{
get { return this.kinect;}
set {
//如果带赋值的传感器和目前的不一样
if (this.kinect!=value)
{
//如果当前的传感对象不为null
if (this.kinect!=null)
{
//uninitailize当前对象
this.kinect=null;
}
//如果传入的对象不为空,且状态为连接状态
if (value!=null&&value.Status==KinectStatus.Connected)
{
this.kinect=value;
}
}
}
} public MainWindow() //构造函数
{
InitializeComponent();
this.Loaded += (s, e) => DiscoverKinectSensor();
this.Unloaded += (s, e) => this.kinect = null;
} private void DiscoverKinectSensor()
{
KinectSensor.KinectSensors.StatusChanged += KinectSensors_StatusChanged;
this.Kinect = KinectSensor.KinectSensors.FirstOrDefault(x => x.Status == KinectStatus.Connected);
} private void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e)
{
switch (e.Status)
{
case KinectStatus.Connected:
if (this.kinect == null)
this.kinect = e.Sensor;
break;
case KinectStatus.Disconnected:
if (this.kinect == e.Sensor)
{
this.kinect = null;
this.kinect = KinectSensor.KinectSensors.FirstOrDefault(x => x.Status == KinectStatus.Connected);
if (this.kinect == null)
{
//TODO:通知用于Kinect已拔出
}
}
break;
//TODO:处理其他情况下的状态
}
}
}
在构造函数中有两个匿名方法,一个用来监听Loaded事件,一个用来监听Unloaded事件。当卸载时应该将Kinect属性置为空。在窗口的Loaded事件中程序通过DiscoverKinectSensor方法试图调用一个连接了的传感器。在窗体的Loaded和Unloaded事件中注册这两个事件用来初始化和释放Kinect对象,如果应用程序没有找到Kinect对象,将会通知用户。
this.Loaded += (s, e) => DiscoverKinectSensor(); 

DiscoverKinectSensor方法只有两行代码,第一行代码注册StatusChanged事件,第二行代码通过lambda表达式查询集合中第一个处在Connected状态的传感器对象,并将该对象复制给Kinect属性。Kinect属性的set方法确保能都赋值一个合法的Kinect对象。

StatusChanged事件中值得注意的是,当状态为KinectSensor.Connected的时候,if语句限制了应用程序只能有一个kinect传感器,他忽略了电脑中可能连接的其他Kinect传感器。


2 打开传感器

一旦发现了传感器,在应用程序能够使用传感器之前必须对其进行初始化。传感器的初始化包括三个步骤。首先,应用程序必须设置需要使用的数据流,并将其状态设为可用。每一中类型的数据流都有一个Enable方法,该方法可以初始化数据流。每一种数据流都完全不同,在使用之前需要进行一些列的设置。在一些情况下这些设置都在Enable方法中处理了。

初始化之后,接下来就是要确定应用程序如何使用产生的数据流。最常用的方式是使用Kinect对象的一些列事件,每一种数据流都有对应的事件,他们是:ColorImageStream对应ColorFrameReady事件、DepthImageStream对应DepthFrameReady事件、SkeletonStream对象对应SkeletonFrameReady事件。以及AllFramesReady事件。各自对应的事件只有在对应的数据流enabled后才能使用,AllFramesReady事件在任何一个数据流状态enabled时就能使用。

最后,应用程序调用KinectSensor对象的Start方法后,frame-ready事件就会触发从而产生数据。

3 停止传感器

一旦传感器打开后,可以使用KinectSensor对象的Stop方法停止。这样所有的数据产生都会停止,因此在监听frameready事件时要先检查传感器是否不为null。

KinectSensor对象以及数据流都会使用系统资源,应用程序在不需要使用KinectSensor对象时必须能够合理的释放这些资源。在这种情况下,程序不仅要停止传单器,还用注销frameready事件。注意,不要去调用KinectSensor对象的Dispose方法。这将会阻止应用程序再次获取传感器。应用程序必须从启或者将Kinect从新拔出然后插入才能再次获得并使用对象。


private void WindowLoaded(object sender, RoutedEventArgs e) // 窗口加载事件函数
{
foreach (var potentialSensor in KinectSensor.KinectSensors)
{
if (potentialSensor.Status == KinectStatus.Connected)
{
this.sensor = potentialSensor;
break;
}
} if (null != this.sensor)
{
// Turn on the color stream to receive color frames
this.sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30); // Allocate space to put the pixels we'll receive
this.colorPixels = new byte[this.sensor.ColorStream.FramePixelDataLength]; // This is the bitmap we'll display on-screen
this.colorBitmap = new WriteableBitmap(this.sensor.ColorStream.FrameWidth, this.sensor.ColorStream.FrameHeight, 96.0, 96.0, PixelFormats.Bgr32, null);
// 位图宽度,高度,水平分辨率,垂直分辨率,System.Windows.Media.PixelFormat,Palette // Set the image we display to point to the bitmap where we'll put the image data
this.Image.Source = this.colorBitmap; // Add an event handler to be called whenever there is new color frame data
this.sensor.ColorFrameReady += this.SensorColorFrameReady; // Start the sensor!
try
{
this.sensor.Start();
}
catch (IOException)
{
this.sensor = null;
}
} if (null == this.sensor)
{
this.statusBarText.Text = Properties.Resources.NoKinectReady;
}
}

private void WindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (null != this.sensor)
{
this.sensor.Stop();
}
}

private void SensorColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
{
if (colorFrame != null)
{
// Copy the pixel data from the image to a temporary array
colorFrame.CopyPixelDataTo(this.colorPixels); // 需要临时byte数组 // Write the pixel data into our bitmap
this.colorBitmap.WritePixels(
new Int32Rect(, , this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight),
this.colorPixels,
this.colorBitmap.PixelWidth * sizeof(int),
);
}
}
}
private void ButtonScreenshotClick(object sender, RoutedEventArgs e)    // 截屏事件处理
{
if (null == this.sensor)
{
this.statusBarText.Text = Properties.Resources.ConnectDeviceFirst; // 状态栏
return;
} // create a png bitmap encoder which knows how to save a .png file
BitmapEncoder encoder = new PngBitmapEncoder(); // create frame from the writable bitmap and add to encoder
encoder.Frames.Add(BitmapFrame.Create(this.colorBitmap)); string time = System.DateTime.Now.ToString("hh'-'mm'-'ss", CultureInfo.CurrentUICulture.DateTimeFormat); string myPhotos = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); string path = Path.Combine(myPhotos, "KinectSnapshot-" + time + ".png"); // write the new file to disk
try
{
using (FileStream fs = new FileStream(path, FileMode.Create))
{
encoder.Save(fs);
} this.statusBarText.Text = string.Format(CultureInfo.InvariantCulture, "{0} {1}", Properties.Resources.ScreenshotWriteSuccess, path);
}
catch (IOException)
{
this.statusBarText.Text = string.Format(CultureInfo.InvariantCulture, "{0} {1}", Properties.Resources.ScreenshotWriteFailed, path);
}
}

由于第一次编WPF ,倒持半天,总算弄好了~~

Kinect 开发 —— ColorBasic的更多相关文章

  1. Kinect开发文章目录

    整理了一下去年为止到现在写的和翻译的Kinect的相关文章,方便大家查看.另外,最近京东上微软在搞活动, 微软 Kinect for Windows 京东十周年专供礼包 ,如果您想从事Kinect开发 ...

  2. Kinect开发资源汇总

    Kinect开发资源汇总   转自: http://www.sigvc.org/bbs/forum.php?mod=viewthread&tid=254&highlight=kinec ...

  3. Kinect开发学习笔记之(一)Kinect介绍和应用

    Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...

  4. Kinect开发笔记之二Kinect for Windows 2.0新功能

    这是本博客翻译文档的第一篇文章.笔者已经苦逼的竭尽全力的在翻译了.但无奈英语水平也是非常有限.不正确或者不妥当不准确的地方必定会有,还恳请大家留言或者邮件我以批评指正.我会虚心接受. 谢谢大家.   ...

  5. Kinect 开发 —— 杂一

    Kinect 提供了非托管(C++)和托管(.NET)两种开发方式的SDK,如果您用C++开发的话,需要安装Speech Runtime(V11),Kinect for Windows Runtime ...

  6. Kinect 开发 —— 控制PPT播放

    实现Kinect控制幻灯片播放很简单,主要思路是:使用Kinect捕捉人体动作,然后根据识别出来的动作向系统发出点击向前,向后按键的事件,从而使得幻灯片能够切换. 这里的核心功能在于手势的识别,我们在 ...

  7. Kinect 开发 —— 全息图

    Kinect的另一个有趣的应用是伪全息图(pseudo-hologram).3D图像可以根据人物在Kinect前面的各种位置进行倾斜和移动.如果方法够好,可以营造出3D控件中3D图像的效果,这样可以用 ...

  8. Kinect 开发 —— 进阶指引(上)

    本文将会介绍一些第三方类库如何来帮助处理Kinect传感器提供的数据.使用不同的技术进行Kinect开发,可以发掘出Kinect应用的强大功能.另一方面如果不使用这些为了特定处理目的而开发的一些类库, ...

  9. Kinect开发 —— 基础知识

    转自:http://www.cnblogs.com/yangecnu/archive/2012/04/02/KinectSDK_Application_Fundamentals_Part2.html ...

随机推荐

  1. Nginx的日志管理

        vim /usr/local/nginx/conf/nginx.conf                                  #编辑 nginx 配置文件     server{ ...

  2. js中return 、return false 、return true、break、continue区别

    在开发中不熟悉这三者区别的同学,一般都知道return可以中止,但会根据字面意思觉得return true 中止当前函数执行,但其后的函数还会继续执行.return false 中止当前函数执行,其后 ...

  3. 洛谷1525 关押罪犯NOIP2010 并查集

    问题描述 S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两 ...

  4. Visual Studio2008 和2010 执行程序出现的黑框马上消失解决方法

    1 在程序最后加         system("PAUSE");  要注意包括头文件#include"stdlib.h"   //system须要调用这个   ...

  5. 51Nod 1405 树的距离之和(dp)

    1405 树的距离之和 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 给定一棵无根树,如果它有n个节点,节点编号从1到n, 求随意两点之间的距离( ...

  6. HDU 4572 Bottles Arrangement

    具体的证明:点击打开链接 我的想法: 要想保证题目所说 构造最小行的和,仅仅能是这样的情况 .....      m-3  m-2  m-1  m    |   m  m-1  m-2  m-3   ...

  7. CSS响应式布局到底是什么?

    响应式布局是最近几年在前端开发中非常火热的词,它是相对于固定像素大小的网页而言的,那么CSS响应式布局到底是什么?顾名思义,响应式布局就是网页能够响应各种各样不同分辨率大小的设备,能够将网页很好的呈献 ...

  8. 负载均衡-lvs

    常用的负载均衡技术比较DNS 轮询DNS本身的机制不再赘述,这里主要看一看基于DNS的负载均衡,其大致原理很清楚,DNS系统本身支持同一个域名映射到多个ip (A记录),例如 这样每次向DNS系统询问 ...

  9. HDU 3374 String Proble

    String Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  10. SQL保存XML报错 “XML 分析: 行 1,字符 47,非法的 xml 字符”

    例如: <?xml version="1.0" encoding="utf-8" standalone="yes"?> < ...