曾经微软宣传Kinect宣传的很火,但一直没有舍得买一台。第一次接触是在某个hackathon上,想做一个空气鼠标的项目,借助Kinect实现的,感觉这个产品挺惊艳。最近想方设法借到一台一代的Kinect for Windows,还有微软官方的开发书籍(《Kinect应用开发实战——用最自然的方式与机器对话》),略研究了下Kinect的开发。
一、环境配置
关于Kinect的介绍网上有很多资料,这里不再赘述。既然是开发微软自家的产品,肯定要上微软全家桶,VS2015(C#)+SDK V1.8+Developer toolkit V1.8。其中SDK可以直接在微软官网上下载,除了官方SDK,还有其它的SDK,我不是很了解,所以不敢妄言介绍。一代Kinect有windows和xbox 360两个版本,windows版本的Kinect前面写着“Kinect”,而xbox 360版本前面写着“xbox 360”,xbox版的连接电脑需要有转接线,但是很诡异的是我曾经直接用xbox版的连接电脑也成功了。并且我最开始安装的SDK是V2.0,也能成功跑起来Kinect V1……虽说SDK V2.0只能驱动二代Kinect,但也许微软还是照顾了旧版本的硬件吧。不过为了稳妥,还是安装SDK V1.8,并且使用Kinect for Windows。
将Kinect连接上电脑之后,可以打开Developer toolkit browser,运行其中某一个demo,来检验Kinect是否正常工作。一般情况下,正常工作是Kinect正面绿灯一直亮。在这里不得不吐槽下Kinect的电源线质量问题,两次接触Kinect都是电源线有问题。这时只有USB供电,电压不足,状态是红灯一直亮,这种情况下更换电源线就好了。
二、正式开发
环境配好之后,打开VS2015,新建一个WPF窗体工程的解决方案,然后在引用里面添加Kinect v1.8,然后在程序中using Microsoft.Kinect即可。Kinect视频方面主要包括采集彩色数据、采集深度数据、追踪骨骼三个功能,此外还有通过麦克风阵列采集声音数据。
三、第一个程序
Kinect有两个摄像头,分别是彩色摄像头和深度摄像头,所以第一个程序就是实现获取两个摄像头采集到的彩色视频流和深度视频流。在MainWindow.xaml文件里,在工具箱中选中Image,向窗体中添加两个大小为640*480的Image,不重叠,分别命名为depthImage和colorImage;在Window标签中添加属性Loaded="Window_Loaded" Closed=Window_Closed,最终Xaml文件代码如下:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:KinectWpfApplication1"
xmlns:WpfViewers="clr-namespace:Microsoft.Samples.Kinect.WpfViewers;assembly=Microsoft.Samples.Kinect.WpfViewers" x:Class="KinectWpfApplication1.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="590" Width="1296"
Loaded="Window_Loaded"
Closed="Window_Closed">
<Grid>
<Image x:Name="depthImage" HorizontalAlignment="Left" Height="480" Margin="650,0,-0.4,0" VerticalAlignment="Top" Width="640"/>
<Image x:Name="colorImage" HorizontalAlignment="Left" Height="480" VerticalAlignment="Top" Width="640"/>
</Grid>
</Window>
Kinect的调用是使用已经封装好的KinectSensor类,用于管理Kinect资源。该类同样支持多个Kinect同时工作,因为我只弄到一台,所以多台Kinect的情况不予考虑。定义KinectSensor _kinect;在Window_Load()中添加函数StartKinect(),然后定义StartKinect函数如下:
private void StartKinect()
{
if (KinectSensor.KinectSensors.Count <= 0)
{
MessageBox.Show("No Kinect device foound!");
return;
}
_kinect = KinectSensor.KinectSensors[0];
//MessageBox.Show("Status:" + _kinect.Status);
_kinect.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
_kinect.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
_kinect.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(KinectColorFrameReady);
_kinect.DepthFrameReady += new EventHandler<DepthImageFrameReadyEventArgs>(KinectDepthFrameReady);
//_kinect.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(_kinect_AllFr