ブログ@kaorun55

HoloLensやKinectなどのDepthセンサーを中心に書いています。

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


続いて距離カメラの画像を扱ってみます。距離カメラも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