Over the Thanksgiving break I managed to get my new Kinect for Windows 2 working with XNA. I couldn't find any code samples online using XNA with the new Kinect SDK, so hopefully this will help out others who are trying to do something similar.
This demo will show how to display the Kinect's video feed which is provided by its 1080p color camera. This is similar to the Color Basics-WPF C# Sample provided in the Kinect SDK 2 except that it is tailored for XNA.
Prerequisites
You must have the Kinect for Windows 2 correctly installed along with the SDK. There are plenty of online tutorials showing you how to program with the older Kinect; this is for the latest version.
Microsoft is no longer maintaining XNA, but but you can still use it in Visual Studio 2013. There are two different ways to get XNA working with VS2013:
Quick Way
Install XNA 4.0 Refresh for VS 2013. The zip file contains four components that you will need to install in succession.
Long Way
If you have VS 2010 laying around, this method will also work although it takes much longer. I found this method necessary when installing XNA in a lab setting. Using the Quick Way would not work for users who were not administrators.
- Install Visual Studio 2010. Any edition will work.
- Install Games for Windows Marketplace Client
- Install XNA Game Studio 4.0
- Install XNA 4.0 Refresh for VS 2013. After you have downloaded the zip file, extract it and run XNA Game Studio 4.0.vsix
If you want to skip both these options, you might try MonoGame. Just be aware that it does not have a content pipeline converter (software that converts content like sound files into xnb files). I have not tried MonoGame with Kinect, but I don't see any reason why it wouldn't work.
Create an XNA Project
First create an XNA project by selecting File → Project... from the menu. Then select XNA Game Studio 4.0 template under Visual C# and select Windows Game (2.0). Name the project KinectVideoXna.Add Kinect Reference
Right-click the project in the Solution Explorer and from the context menu select Add → Reference.... Type kinect in the dialog box's search box, and check the Microsoft.Kinect reference. Then press OK. You should now see Microsoft.Kinect among the project's References in the Solution Explorer.
Adding Code
Add the Kinect namespace:
using Microsoft.Kinect;
Add some class-level variables:
// Texture to draw Texture2D videoTexture; // Active Kinect sensor private KinectSensor kinectSensor; // Reader for color frames private ColorFrameReader colorFrameReader; // Intermediate storage for receiving frame data from the sensor private byte[] colorPixels;
Initialize the sensor and the data structures used for capturing data from the sensors:
protected override void Initialize() { kinectSensor = KinectSensor.GetDefault(); // Open the reader for the color frames colorFrameReader = kinectSensor.ColorFrameSource.OpenReader(); // Specify a handler for frame arrival colorFrameReader.FrameArrived += Reader_ColorFrameArrived; // Create the ColorFrameDescription using rgba format FrameDescription desc = kinectSensor.ColorFrameSource. CreateFrameDescription(ColorImageFormat.Rgba); // Allocate space to put the pixels to be rendered colorPixels = new byte[desc.Width * desc.Height * desc.BytesPerPixel]; // Open the sensor kinectSensor.Open(); // Create texture large enough to hold the color frame videoTexture = new Texture2D(graphics.GraphicsDevice, desc.Width, desc.Height); base.Initialize(); }
Also override the OnExiting
method to free up the ColorFrameReder
and Kinect sensor when the game exists:
protected override void OnExiting(object sender, EventArgs args) { if (colorFrameReader != null) { colorFrameReader.Dispose(); colorFrameReader = null; } if (kinectSensor != null) { kinectSensor.Close(); kinectSensor = null; } base.OnExiting(sender, args); }
Create the handler for the color photo sensor where we'll store the captured photo into videoTexture:
private void Reader_ColorFrameArrived(object sender, ColorFrameArrivedEventArgs e) { // ColorFrame is IDisposable using (ColorFrame colorFrame = e.FrameReference.AcquireFrame()) { if (colorFrame != null) { // Copy color frame into the array colorFrame.CopyConvertedFrameDataToArray( colorPixels, ColorImageFormat.Rgba); // Avoid exception when SetData method is used GraphicsDevice.Textures[0] = null; // Put pixel data into a texture videoTexture.SetData(colorPixels); } } }
Finally, draw the videoTexture containing the color photo to the screen:
protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); if (videoTexture != null) { // Draw color video spriteBatch.Begin(); spriteBatch.Draw(videoTexture, new Rectangle(0, 0, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height), Color.White); spriteBatch.End(); } base.Draw(gameTime); }
Press Ctrl-F5 to build and run the program. You should see color video of whatever your Kinect is pointed at.
Problems?
When I first tried to build and run my program, I got the following error message:
The primary reference "Microsoft.Kinect, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" could not be resolved because it was built against the ".NETFramework,Version=v4.5" framework. This is a higher version than the currently targeted framework ".NETFramework,Version=b4.0".To fix this problem, I closed the project in Visual Studio and opened the project's .csproj file in a text editor and changed the following line:
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>to
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>Then I re-opened the project in Visual Studio and re-built the application with no problems.