Members‎ > ‎Wataru-Fujimura‎ > ‎Kinect Tips‎ > ‎

XNAによる実画像取得

XNAでの実画像取得方法です。
(作成日:2012/03/01)


1.プロジェクトを作る

Visual Studioを立ち上げ[ファイル]→[新規作成][プロジェクト]を選び、[XNA Game Studio 4.0]を選択します。



すると新しいプロジェクトが作成されます。




2.参照設定を追加

ソリューションエクスプローラ内の[参照設定]を右クリックし、[参照の追加]をクリック。



[.NET]のタブを選択し、[Microsoft.Kinect]を追加します。



追加されるとこのように表示されます。




3.プログラミング

以下のコードのように入力してください。

実画像のデータはBGRAの順で取得しているようです。

そのまま描画すると色がおかしくなるので、BとRの入れ替え処理を行います。
また取得できるアルファの値は0なので、値を255に設定します。

Game1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

// kinectのセンサクラス
// Microsoft.kinectを参照設定に追加
using Microsoft.Kinect;

namespace xnagetcolorimage
{
    /// <summary>
    /// 基底 Game クラスから派生した、ゲームのメイン クラスです。
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        /// <summary>
        /// KINECTのセンサクラス
        /// </summary>
        private KinectSensor kinect;

        /// <summary>
        /// 実画像テクスチャ
        /// 640x480
        /// </summary>
        private Texture2D imageTexture;

        /// <summary>
        /// kinectから取得したRGBデータ
        /// (byte型配列)
        /// </summary>
        private byte[] imageData;

        /// <summary>
        /// キーボードの状態
        /// </summary>
        private KeyboardState key;

        /// <summary>
        /// 1frame前のキーボードの状態
        /// </summary>
        private KeyboardState oldkey;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            // ウィンドウサイズの指定
            graphics.PreferredBackBufferHeight = 480;
            graphics.PreferredBackBufferWidth = 640;
        }

        /// <summary>
        /// ゲームが実行を開始する前に必要な初期化を行います。
        /// ここで、必要なサービスを照会して、関連するグラフィック以外のコンテンツを
        /// 読み込むことができます。base.Initialize を呼び出すと、使用するすべての
        /// コンポーネントが列挙されるとともに、初期化されます。
        /// </summary>
        protected override void Initialize()
        {
            // TODO: ここに初期化ロジックを追加します。

            // kinectの初期化
            kinect = KinectSensor.KinectSensors[0];

            // カラー画像の取得を開始する
            kinect.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(ColorImageReady);
            kinect.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
            
            // Kinectを起動する
            kinect.Start();
            
            base.Initialize();
        }

        /// <summary>
        /// LoadContent はゲームごとに 1 回呼び出され、ここですべてのコンテンツを
        /// 読み込みます。
        /// </summary>
        protected override void LoadContent()
        {
            // 新規の SpriteBatch を作成します。これはテクスチャーの描画に使用できます。
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: this.Content クラスを使用して、ゲームのコンテンツを読み込みます。
        }

        /// <summary>
        /// UnloadContent はゲームごとに 1 回呼び出され、ここですべてのコンテンツを
        /// アンロードします。
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: ここで ContentManager 以外のすべてのコンテンツをアンロードします。
        }

        /// <summary>
        /// ワールドの更新、衝突判定、入力値の取得、オーディオの再生などの
        /// ゲーム ロジックを、実行します。
        /// </summary>
        /// <param name="gameTime">ゲームの瞬間的なタイミング情報</param>
        protected override void Update(GameTime gameTime)
        {
            // ゲームの終了条件をチェックします。
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: ここにゲームのアップデート ロジックを追加します。

            // キーボードの状態を取得
            key = Keyboard.GetState();

            // Escapeキーが押されたらプログラムを終了する
            if (key.IsKeyDown(Keys.Escape))
                Exit();

            // F1が押されたら[ウィンドウモード⇔フルスクリーンモード]の切り替え
            if (key.IsKeyDown(Keys.F1) && oldkey.IsKeyUp(Keys.F1))
                graphics.ToggleFullScreen();
            
            // このフレームのキーボードの状態を記憶しておく
            oldkey = key;

            base.Update(gameTime);
        }

        /// <summary>
        /// ゲームが自身を描画するためのメソッドです。
        /// </summary>
        /// <param name="gameTime">ゲームの瞬間的なタイミング情報</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: ここに描画コードを追加します。

            // スプライトバッチの使用開始
            spriteBatch.Begin();

            // 実画像の描写
            if (imageTexture != null)
                spriteBatch.Draw(imageTexture, Vector2.Zero, Color.White);

            // スプライトバッチの使用終了
            spriteBatch.End();

            base.Draw(gameTime);
        }

        /// <summary>
        /// カラー画像の取得
        /// </summary>
        void ColorImageReady(object sender, ColorImageFrameReadyEventArgs e)
        {
            // kinectからカラーイメージを取得
            ColorImageFrame image = e.OpenColorImageFrame();

            if (image != null)
            {
                // imageData配列の初期化
                imageData = new byte[image.PixelDataLength];

                // imageのピクセルデータをpixelDataへコピーする
                image.CopyPixelDataTo(imageData);

                int no = 0;

                // 入れ替え用
                byte temp = 0;

                for (int y = 0; y < image.Height; y++)
                {
                    for (int x = 0; x < image.Width; x++, no += 4)
                    {
                        // BGRAからRGBAに変換する
                        temp = imageData[no];
                        imageData[no] = imageData[no + 2];
                        imageData[no + 2] = temp;

                        // Alphaを255にする
                        imageData[no + 3] = 255;
                    }
                }

                // imageTextureの初期化
                imageTexture = new Texture2D(GraphicsDevice, image.Width, image.Height);

                // imageTextureにimageDataを反映する
                imageTexture.SetData(imageData);
            }
        }
    }
}





実行結果

このような感じで表示されるはずです。



ソースコード内の「 kinect.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30); 」を変更することで、取得するサイズ・FPSなど変更できます。

取得できる種類
・RawYuvResolution640x480Fps15
・RgbResolution1280x960Fps12
・RgbResolution640x480Fps30(デフォルト)
・YuvResolution640x480Fps15

ċ
xnagetcolorimage.zip
(58k)
Wataru Fujimura,
Mar 1, 2012, 12:10 AM
Comments