Kinect SDK Extension Methods
In this article I’m sharing a couple of quick extension methods I made for working with the Kinect SDK Beta. I was experimenting with using the Kinect sensor in an XNA project and found myself wanting to do two things; convert the output from the RGB stream to a Texture2D and to get the position of a joint from the sensors skeleton tracking functionality relative to the game screen dimensions.
The following code shows the implementation of these extension methods. I must add that this code is pretty much taken straight out of the samples and that I have just reorganised it to make it a bit easier to use.
public static class KinectExtensions { private static Texture2D texture = null; private static Color[] colorData = null; public static Texture2D ToTexture2D(this PlanarImage image, GraphicsDevice graphicsDevice) { if(texture == null || colorData == null) { texture = new Texture2D(graphicsDevice, image.Width, image.Height, false, SurfaceFormat.Color); colorData = new Color[image.Width * image.Height]; } int index = 0; for (int y = 0; y < image.Height; y++) { for (int x = 0; x < image.Width; x++, index += image.BytesPerPixel) colorData[y * image.Width + x] = new Color(image.Bits[index + 2], image.Bits[index + 1], image.Bits[index + 0]); } texture.SetData(colorData); return texture; } public static Vector2 GetScreenPosition(this Joint joint, Runtime kinectRuntime, int screenWidth, int screenHeight) { float depthX; float depthY; kinectRuntime.SkeletonEngine.SkeletonToDepthImage(joint.Position, out depthX, out depthY); depthX = Math.Max(0, Math.Min(depthX * 320, 320)); //convert to 320, 240 space depthY = Math.Max(0, Math.Min(depthY * 240, 240)); //convert to 320, 240 space int colorX; int colorY; // only ImageResolution.Resolution640x480 is supported at this point kinectRuntime.NuiCamera.GetColorPixelCoordinatesFromDepthPixel(ImageResolution.Resolution640x480, new ImageViewArea(), (int)depthX, (int)depthY, (short)0, out colorX, out colorY); // map back to skeleton.Width & skeleton.Height return new Vector2(screenWidth * colorX / 640.0f, screenHeight * colorY / 480f); } }}
No related posts.
I just wanted to point out that you shouldn’t create a new Texture2D on every frame but rather update the same Texture2D (because it’s always has the same width and height), and it would also be better to reuse the same Color array.
I know there wont be a big difference with simple stuff, but if you’re doing something big then you’ll start noticing the dark side of the Garbage Collector :S
That’s a great point! When I get a chance I’ll update the code in the article to include these changes.
Thanks
Hey Jason,
Did ya manage to update the code yet?
Totally forgot about that! It’s updated now – I haven’t tested it but it **should** work. You should maybe also take a look at http://jason-mitchell.com/programming/xna-texture2d-creation-byte-vs-color/