我正在尝试使用Kinect v2 Color和Skeleton Stream在MonoGame的头部关节上绘制一个简单的框(texture2d)。请纠正我在哪里犯错误?
以下是我的代码的输出:(看到红色框没有在头上映射)
请查找附上我的代码:
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Kinect;
#endregion
namespace KinectColorBasicInMonogame
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Game
{
GraphicsDeviceManager graphics;
Texture2D textureHead;
Texture2D videoTexture;
SpriteBatch spriteBatch;
private Matrix world = Matrix.CreateTranslation(new Vector3(0, 0, 0));
private Matrix view = Matrix.CreateLookAt(new Vector3(0, 0, 60), new Vector3(0, 0, 0), Vector3.UnitY);
private Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800 / 480f, 0.1f, 100f);
//*******************************
// Kinect variables
//********************************
//Skeleton Variables
private KinectSensor kinectSensor = null;
private CoordinateMapper coordinateMapper = null;
private BodyFrameReader bodyFrameReader = null;
private Body[] bodies = null;
private JointType[] headJoints = new JointType[6];
Vector2 headPos2d;
// cOLOR STREAM VARIABLE
private ColorFrameReader colorFrameReader;
private byte[] colorPixels;
public Game1()
: base()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
headPos2d = new Vector2(0,0);
// Kinect variables initialization
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];
//******SKELTON*****
this.coordinateMapper = this.kinectSensor.CoordinateMapper;
FrameDescription frameDescription = this.kinectSensor.DepthFrameSource.FrameDescription;
this.bodyFrameReader = this.kinectSensor.BodyFrameSource.OpenReader();
this.bodyFrameReader.FrameArrived += this.Reader_FrameArrived;
// 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();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
Content = new ContentManager(this.Services, "Content");
spriteBatch = new SpriteBatch(GraphicsDevice);
textureHead = Content.Load<Texture2D>("img");
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
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);
}
//*******SKELETON EVENT***********
private void Reader_FrameArrived(object sender, BodyFrameArrivedEventArgs e)
{
bool dataReceived = false;
using (BodyFrame bodyFrame = e.FrameReference.AcquireFrame())
{
if (bodyFrame != null)
{
if (this.bodies == null)
{
this.bodies = new Body[bodyFrame.BodyCount];
}
bodyFrame.GetAndRefreshBodyData(this.bodies);
dataReceived = true;
}
}
if (dataReceived)
{
for (int i = 0; i < bodies.Length; i++)
{
Body body = bodies[i];
if (body.IsTracked)
{
headJoints[i] = JointType.Head;
UpdateHeadInfo(headJoints[i], body);
}
}
}
}
private void UpdateHeadInfo(JointType head, Body body)
{
CameraSpacePoint position = body.Joints[JointType.Head].Position;
ColorSpacePoint colorSpacePoint = kinectSensor.CoordinateMapper.MapCameraPointToColorSpace(position);
headPos2d = new Vector2(colorSpacePoint.X, colorSpacePoint.Y);
}
//*******COLOR EVENT***********
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);
}
}
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
if (videoTexture != null)
{
// Draw color video
spriteBatch.Draw(videoTexture, new Rectangle(0, 0, graphics.GraphicsDevice.Viewport.Width,
graphics.GraphicsDevice.Viewport.Height), Color.White);
}
spriteBatch.Draw(textureHead, headPos2d, Color.Red);
spriteBatch.End();
base.Draw(gameTime);
}
}
}