ブログトップ 記事一覧 ログイン 無料ブログ開設

かおるんダイアリー RSSフィード Twitter

2012年02月01日

Kinect for Windows SDK の正式版がリリースされました

f:id:kaorun55:20120202024606p:image

本日、待望のKinect for Windows SDK の正式版がリリースされました。

Kinect for Windowsもこちらから購入できるようです(限定らしいので確実に買えるかはわかりません)。


合わせて様々な情報もリリースされています。


Kinect for Windows SDK 1.0の特長

間違いなどあれば、ご指摘ください

  • 商用利用が可能
    • 商用利用のために、ユーザーランタイムを同梱
  • 最大4台までのKinectを接続可能
  • スケルトントラッキングの性能上(Xbox 360並み)
  • 近接モードにより40cmからのプレーヤー、スケルトン・トラッキングが可能
  • Microsoft Speech SDK V.11 に対応
  • さまざまなAPIのアップデート
    • 例のRuntimeは名称が変更されていますw
  • サンプルのアップデート
  • 年に2-3回のSDKアップデート(要出展)
  • .@UnaNancyOwen さんのKinect SDK ファーストインプレッション - Togetter より
    • 開発用SDKとユーザーランタイムは別
    • 開発用SDKではKinect for Xbox(従来のKinect)は利用可能
    • ユーザーランタイムではKinect for Windows(新しいKinect)のみ利用可能
    • 近接モードはfor Xboxでは利用できない

APIレベルでの Kinect for Windows SDK Beta2からの変更点

Beta2とはなんだったのか。と言わんばかりの変更量ですw ただ、扱いやすくなっているので、うれしいですね。

  • KinectSensorクラス(旧Runtime)にRGB,Depth,Player,Skeleton,Audioが統合された。
  • より簡単な制御
  • FrameReadyイベントに渡される引数のインタフェースがだいぶ変わった
  • RGBとDepthの解像度が同じなった(640x480)
  • Depthに近接モードのためのフィールドが追加
  • PlayerはDepthからSkeletonの機能に
  • Map系のメソッドの拡充(RGB<->Skeleton<->Depth<->RGB)

簡単なサンプル


Kinect for Windows

肝心の Kinect for Windows ですが、アメリカ圏ではすでに購入できるようです。

今もっている情報では、日本でも2/2から購入が可能になるそうです。ただし、Amazonや一般の販売店では購入できないようです。

購入先の情報が更新されたら、こちらからもリンクを張ろうかと思います。

こちらから購入できるようです(限定らしいので確実に買えるかはわかりません)。


Amazonにも載りました

マイクロソフト 【商業用】Kinect for Windows センサー L6M-00005

マイクロソフト 【商業用】Kinect for Windows センサー L6M-00005

Kinect for Windows SDK のインストール

Kinect for Windows SDK をインストールしてみましょう。


必要なもの


インストール手順

  1. Kinect をコンピューターからはずします
  2. Beta版のアンインストール
    • Beta版の Kinect for Windows SDK がインストールされている場合は、削除してください
  3. ここからインストーラをダウンロードします
    • 32bit版と64bit版ともに同じインストーラです
  4. インストーラの通りにインストールします
    • f:id:kaorun55:20120202040932p:image:w480
    • f:id:kaorun55:20120202040931p:image:w480
    • f:id:kaorun55:20120202040930p:image:w480
  5. Kinect をコンピューターに接続します
    • f:id:kaorun55:20120202040933p:image:w480
  6. スタートメニューの「Microsoft Kinect SDK v1.0|Kinect SDK Sample Browser」を起動します
    • f:id:kaorun55:20120202040934p:image:w480
  7. Kinect Explorerを起動して、画像が表示されればOKです
    • f:id:kaorun55:20120202040929p:image:w480

おまけ

Coding4Fun Kinect Toolkit というライブラリが、C#で実装する場合にとても役に立つので、ぜひダウンロードしてください。

以降のサンプルでは、このライブラリを利用します。

Kinect for Windows SDK で RGBカメラの画像を表示する(C# + WPF)

f:id:kaorun55:20120202043450p:image

実際にKinect SDKを使ったアプリケーションを作ってみましょう

全体のコードはこちらにあります


プロジェクトの作成

  1. プロジェクトを作成します。今回はC#とWPFで作ります。
    • f:id:kaorun55:20120202043449p:image
  2. Kinect SDKとKinect Toolkitを参照に加えます
    • f:id:kaorun55:20120202043451p:image

コード

続いてコードです

XAML
<Window x:Class="RgbCamera.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="RgbCamera" Height="521" Width="663" SizeToContent="Manual">
    <Grid>
        <Image Name="imageRgbCamera" Margin="0" Stretch="Uniform" />
    </Grid>
</Window>

Image を一つ使います。最大化されたときにも広がるように、StretchをUniformに設定します。



CS
using System;
using System.Windows;
using Coding4Fun.Kinect.Wpf;
using Microsoft.Kinect;

namespace RgbCamera
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            try {
                if ( KinectSensor.KinectSensors.Count == 0 ) {
                    throw new Exception( "Kinectが接続されていません" );
                }

                // Kinectインスタンスを取得する
                KinectSensor kinect = KinectSensor.KinectSensors[0];

                // Colorを有効にする
                kinect.ColorFrameReady +=
                    new EventHandler<ColorImageFrameReadyEventArgs>( kinect_ColorFrameReady );
                kinect.ColorStream.Enable();

                // Kinectの動作を開始する
                kinect.Start();
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message );
                Close();
            }
        }

        void kinect_ColorFrameReady( object sender, ColorImageFrameReadyEventArgs e )
        {
            imageRgbCamera.Source = e.OpenColorImageFrame().ToBitmapSource();
        }
    }
}

Beta2までと比べてとてもすっきりしています。


Runtimeクラスは、KinectSensor クラスに改められています。

Runtime.Initializeは不要になり、設定なしでRGB,Depth,Player,Skeleton,Audioが利用可能です。

またVideoStreamもColorStreamに変更されており、ColorFrameReady でイベント設定、ColorStream.Enableでカメラを有効にします。Enableの引数にColorImageFormatを渡すことで、解像度とフレームレートを変更することができまう。設定できる解像度は次の4つで、デフォルトはRgbResolution640x480Fps30のようです。

  1. RawYuvResolution640x480Fps15
  2. RgbResolution1280x960Fps12
  3. RgbResolution640x480Fps30
  4. YuvResolution640x480Fps15

カメラの設定が終わったところで、KinectSensor.Startを呼び出します。これによってセンサーからデータの取得を開始します。


RGB画像の更新準備ができたらColorFrameReadyが呼ばれます。引数の内容も変わっており、e.OpenColorImageFrame()でColorImageFrameクラスが取得できます。この中に実際の画像データが入っています。

ColorImageFrameクラスはKinect Toolkitによって拡張メソッドが提供されているので、ToBitmapSource()を呼ぶことでBitmapSourceクラスに変換可能です。変換されたBitmapSourceをそのままImage.Source に突っ込めばOKです。


まとめ

とても簡単ですね。

Kinect Toolkitも正式版に対応しているため、さらに簡単に実装することができます。

なお、Kinect Toolkitはソースも公開されてますので、のぞいてみることでかなり勉強になります。

Kinect for Windows SDK で 距離カメラの画像を表示する(C# + WPF)

f:id:kaorun55:20120202100950p:image

続いて距離カメラの画像を扱ってみます。距離カメラもRGBカメラと同じように扱うことができます。

Beta2からの変更点

  • 距離データはshortの配列。Beta2までのようにbyte配列をshortに組み直す必要はない
  • 距離カメラからのデータは、プレーヤーの検出状態にかかわらず16bit/1pixelの上位13bit。こちらはBeta2と同じようにビット演算する必要がある
    • bit演算するための値は、プレーヤーインデックスを取得するためのPlayerIndexBitmask(値:7)と、実際の距離を取得するためのPlayerIndexBitmaskWidth(値:3)がそれぞれDepthImageFrameに定義されている

コード

それではコードを見てみましょう。全体のコードはこちらにあります。


XAML
<Window x:Class="DepthCamera.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DepthCamera" Height="521" Width="663">
    <Grid>
        <Image Name="imageRgbCamera" Stretch="Uniform" />
        <Image Name="imageDepthCamera" Stretch="Uniform" Opacity="0.7" />
    </Grid>
</Window>

Image を2つ使います。下に追加したimageDepthCameraが上(あと)に描画されます。そのためOpacityですこし透過させ、RGBにかぶせています。



CS
using System;
using System.Windows;
using Coding4Fun.Kinect.Wpf;
using Microsoft.Kinect;

namespace DepthCamera
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            try {
                if ( KinectSensor.KinectSensors.Count == 0 ) {
                    throw new Exception( "Kinectが接続されていません" );
                }

                // Kinectインスタンスを取得する
                KinectSensor kinect = KinectSensor.KinectSensors[0];

                // Colorを有効にする
                kinect.ColorFrameReady +=
                    new EventHandler<ColorImageFrameReadyEventArgs>( kinect_ColorFrameReady );
                kinect.ColorStream.Enable();

                // Depthを有効にする
                kinect.DepthFrameReady +=
                    new EventHandler<DepthImageFrameReadyEventArgs>( kinect_DepthFrameReady );
                kinect.DepthStream.Enable();

                // Kinectの動作を開始する
                kinect.Start();
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message );
                Close();
            }
        }

        // RGBカメラのフレーム更新イベント
        void kinect_ColorFrameReady( object sender, ColorImageFrameReadyEventArgs e )
        {
            imageRgbCamera.Source = e.OpenColorImageFrame().ToBitmapSource();
        }

        // 距離カメラのフレーム更新イベント
        void kinect_DepthFrameReady( object sender, DepthImageFrameReadyEventArgs e )
        {
            imageDepthCamera.Source = e.OpenDepthImageFrame().ToBitmapSource();
        }
    }
}

RGBと同じですね。

DepthFrameReady にフレーム更新イベントを登録し、DepthStream.Enableで距離カメラを有効にします。DepthStream.Enableも解像度を設定することができ、サポートされる解像度は次の3つです。

  1. Resolution320x240Fps30
  2. Resolution640x480Fps30
  3. Resolution80x60Fps30

試してませんが、ColorとDepthの座標合わせはDepthImageFrame.MapToColorImagePointでできるんじゃないかなぁと思ってます


近接モードについて

Kinect for Windows のウリの一つである近接モード(Near Mode)は DepthImageStream.Range で設定できるようです。Rangeはenum DepthRangeとして定義されており、DefaultとNearの2種類があります。Defaultは従来のモード、Nearが近接モードになります。近接モードはKinect for Windowsのみ利用可能ということで、まだ確認はできていませんが、こちらに解説が載っています。

引用すると、通常モードは80cm - 4m、近接モードは40cm - 3mをサポートするようです。

http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-49-02/7750.Distance-from-Sensor_5F00_Kinect-default-and-near-mode.png


またこちらを見ると、近接モードでのスケルトン・トラッキングはCenter hipのみ検出可能で、それ以外のjointは現在のバージョンでは検出できないようです。但し書きがついているので、今後は改善されるのでしょう。

http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-49-02/2158.Table_5F00_Kinect-for-Windows-default-and-near-mode.jpg

Kinect for Windows SDK で プレーヤーを認識させる(C# + WPF)

f:id:kaorun55:20120202105929p:image

次はプレーヤーです。

Kinect Toolkitを利用している場合は、前回のコードから一行追加するだけです。


コード

全体のコードはこちらにあります。


public MainWindow()
{
    InitializeComponent();
    try {
        if ( KinectSensor.KinectSensors.Count == 0 ) {
            throw new Exception( "Kinectが接続されていません" );
        }

        // Kinectインスタンスを取得する
        KinectSensor kinect = KinectSensor.KinectSensors[0];

        // Colorを有効にする
        kinect.ColorFrameReady +=
            new EventHandler<ColorImageFrameReadyEventArgs>( kinect_ColorFrameReady );
        kinect.ColorStream.Enable();

        // Depthを有効にする
        kinect.DepthFrameReady +=
            new EventHandler<DepthImageFrameReadyEventArgs>( kinect_DepthFrameReady );
        kinect.DepthStream.Enable();

        // Skeletonを有効にするとプレーヤーが取得できる
        kinect.SkeletonStream.Enable();

        // Kinectの動作を開始する
        kinect.Start();
    }
    catch ( Exception ex ) {
        MessageBox.Show( ex.Message );
        Close();
    }
}

追加されたコードは kinect.SkeletonStream.Enable() の部分のみです。

自前でやろうとした場合は、DepthImageFrameに定義されている、プレーヤーインデックスを取得するためのPlayerIndexBitmask(値:7)を使ってpixelごとに抜き出すことになるでしょう。

Kinect for Windows SDK でスケルトンを表示する(C# + WPF)

f:id:kaorun55:20120202112351p:image

画像系の最後として、スケルトンを表示してみましょう。

スケルトンの表示方法もBeta2に比べて簡単になっています。


コード

それではコードを見てみましょう。全体のコードはこちらにあります。


XAML
<Window x:Class="SkeletonSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Skeleton" Height="521" Width="663">
    <Grid>
        <Image Name="imageRgbCamera" Stretch="Uniform" />
        <Image Name="imageDepthCamera" Stretch="Uniform" Opacity="0.7" />
        <Canvas Name="canvas1" />
    </Grid>
</Window>

スケルトンのjointを配置するためのCanvasを一つ追加します。そのほかは、前回までと同じです。



CS
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using Coding4Fun.Kinect.Wpf;
using Microsoft.Kinect;

namespace SkeletonSample
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        KinectSensor kinect;

        public MainWindow()
        {
            InitializeComponent();

            try {
                if ( KinectSensor.KinectSensors.Count == 0 ) {
                    throw new Exception( "Kinectが接続されていません" );
                }

                // Kinectインスタンスを取得する
                kinect = KinectSensor.KinectSensors[0];

                // すべてのフレーム更新通知をもらう
                kinect.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>( kinect_AllFramesReady );

                // Color,Depth,Skeletonを有効にする
                kinect.ColorStream.Enable();
                kinect.DepthStream.Enable();
                kinect.SkeletonStream.Enable();

                // Kinectの動作を開始する
                kinect.Start();
            }
            catch ( Exception ex ) {
                MessageBox.Show( ex.Message );
                Close();
            }
        }

        // すべてのデータの更新通知を受け取る
        void kinect_AllFramesReady( object sender, AllFramesReadyEventArgs e )
        {
            imageRgbCamera.Source = e.OpenColorImageFrame().ToBitmapSource();
            imageDepthCamera.Source = e.OpenDepthImageFrame().ToBitmapSource();

            // 骨格位置の表示
            ShowSkeleton( e );
        }

        private void ShowSkeleton( AllFramesReadyEventArgs e )
        {
            // キャンバスをクリアする
            canvas1.Children.Clear();

            // スケルトンフレームを取得する
            SkeletonFrame skeletonFrame = e.OpenSkeletonFrame();
            if ( skeletonFrame != null ) {
                // スケルトンデータを取得する
                Skeleton[] skeletonData = new Skeleton[skeletonFrame.SkeletonArrayLength];
                skeletonFrame.CopySkeletonDataTo( skeletonData );

                // プレーヤーごとのスケルトンを描画する
                foreach ( var skeleton in skeletonData ) {
                    if ( skeleton.TrackingState == SkeletonTrackingState.Tracked ) {
                        // 骨格を描画する
                        foreach ( Joint joint in skeleton.Joints ) {
                            // 骨格の座標をカラー座標に変換する
                            ColorImagePoint point = kinect.MapSkeletonPointToColor( joint.Position, kinect.ColorStream.Format );

                            // 円を書く
                            canvas1.Children.Add( new Ellipse()
                            {
                                Margin = new Thickness( point.X, point.Y, 0, 0 ),
                                Fill = new SolidColorBrush( Colors.Black ),
                                Width = 20,
                                Height = 20,
                            } );
                        }
                    }
                }
            }
        }
    }
}

すこし変えてみました。

フレーム更新イベントをAllFramesReadyを使ってひとまとめにしました。AllFramesReadyはRGB,Depth,Skeletonをまとめて通知してくれるイベントです。

// すべてのフレーム更新通知をもらう
kinect.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>( kinect_AllFramesReady );

kinect_AllFramesReadyでは、RGB,Depth,Skeletonをそれぞれ描画します。Skeletonは少し手間なので、メソッドに切り出しました。

// すべてのデータの更新通知を受け取る
void kinect_AllFramesReady( object sender, AllFramesReadyEventArgs e )
{
    imageRgbCamera.Source = e.OpenColorImageFrame().ToBitmapSource();
    imageDepthCamera.Source = e.OpenDepthImageFrame().ToBitmapSource();

    // 骨格位置の表示
    ShowSkeleton( e );
}

スケルトンの描画です。

  1. 最初にOpenSkeletonFrameを取得します。
  2. 続いてSkeletonを取得します。Skeletonの数はSkeletonFrame.SkeletonArrayLengthで取得できるので、容量分の配列を確保しSkeletonFrame.CopySkeletonDataToで取得します。
  3. あとはSkeletonおよびJointで回して描画します。Skeletonの座標をRGBの座標に変換するために、KinectSensor.MapSkeletonPointToColorを使っています。
  4. KinectSensor.MapSkeletonPointToColorで取得された、SkeletonのRGB座標を利用して、Canvasに円を書いています
private void ShowSkeleton( AllFramesReadyEventArgs e )
{
    // キャンバスをクリアする
    canvas1.Children.Clear();

    // スケルトンフレームを取得する
    SkeletonFrame skeletonFrame = e.OpenSkeletonFrame();
    if ( skeletonFrame != null ) {
        // スケルトンデータを取得する
        Skeleton[] skeletonData = new Skeleton[skeletonFrame.SkeletonArrayLength];
        skeletonFrame.CopySkeletonDataTo( skeletonData );

        // プレーヤーごとのスケルトンを描画する
        foreach ( var skeleton in skeletonData ) {
            if ( skeleton.TrackingState == SkeletonTrackingState.Tracked ) {
                // 骨格を描画する
                foreach ( Joint joint in skeleton.Joints ) {
                    // 骨格の座標をカラー座標に変換する
                    ColorImagePoint point = kinect.MapSkeletonPointToColor( joint.Position, kinect.ColorStream.Format );

                    // 円を書く
                    canvas1.Children.Add( new Ellipse()
                    {
                        Margin = new Thickness( point.X, point.Y, 0, 0 ),
                        Fill = new SolidColorBrush( Colors.Black ),
                        Width = 20,
                        Height = 20,
                    } );
                }
            }
        }
    }
}

このようにBeta2とそれほど変わらずに、すこし簡単になっているスケルトンでした。

【注】このサイトの記事を実践する場合はすべて自己責任で行ってください