Kinectで距離カメラの値を取得して、指定した距離で人物が背景に溶け込むサンプル

2012年8月8日(水)
薬師寺 国安

※前ページからの続きです。

ウィンドウが読み込まれた時の処理

Kinect センサーが接続されていない場合は、警告を発して処理を抜けます。そうでない場合は、Kinect センサーを取得します。
DepthStream.Enableメソッドで距離カメラの表示サイズを640×480、1秒あたり30フレームで、動作を開始します。
同様にColorStream.Enableメソッドで、RDBカメラを、RGBフォーマット、表示サイズ640×480、1秒あたり30フレームで、動作を開始します。プレイヤーおよびスケルトンの認識も開始します。

Dim myDepthStream As DepthImageStream = kinect.DepthStreamで、距離カメラの処理を行うクラスのインスタンスを取得します。

Dim myColorStream As ColorImageStream = kinect.ColorStreamで、RGBカメラの処理を行うクラスのインスタンスを取得します。

Short配列変数myDepthPixelDataに、距離カメラのピクセルデータのバイト長分の配列を作成します。
640×480の表示サイズの場合は、myDepthPixelData=New Short(307200-1){}分の配列を確保することになります。-1しているのは配列のインデックスは0から始まるためです。

バイト配列変数myColorPixelDataに、RGBカメラのピクセルデータのバイト長分の配列を作成します。
WriteableBitmapクラス型のPersonを下記の書式で初期化します。

New WriteableBitmap(距離カメラのフレーム幅,距離カメラのフレーム高さ, ビットマップの水平値, ビットマップの垂直値,ビットマップのピクセルフォーマット,ビットマップのビットマップパレット)

ビットマップのピクセルフォーマットに指定する、PixelFormats.Bgra32は、Bgra32 ピクセル形式を取得します。Bgra32 は、bits per pixel (BPP) が 32 の sRGB 形式です。
各カラー チャネル (青、緑、赤、およびアルファ) に割り当てられるbits per pixel (BPP) は 8 になります。これで、Personオブジェクトの表示形式が設定されます。

Person = New WriteableBitmap(640, 480, 96, 96, PixelFormats.Bgra32, Nothing)

と指定しても同じです。

IntRect32構造体のmyImageRectを下記の書式で初期化し、領域を指定します。

New IntRect32(新しいInt32Rect のインスタンスの X座標,新しいInt32Rect のインスタンスの Y座標, 四角形の幅を指定した新しい Int32Rect のインスタンスの幅, 四角形の高さを指定した新しい Int32Rect のインスタンスの高さ)

新しいInt32Rect のインスタンスの X座標と、新しいInt32Rect のインスタンスの Y座標には0を指定します。四角形の幅を指定した新しい Int32Rect のインスタンスの幅には、Personオブジェクトの幅を指定し、Int32Rect のインスタンスの高さには、Personオブジェクトの高さを指定します。結局は、以下のように指定しても同じことです。

myImageRect = New Int32Rect(0, 0, 640, 480)

Kinectを動作させます。

構成ツリーのオブジェクトがレンダリングされる直前に発生する、CompositionTarget.Renderingイベントにイベントハンドラを指定します。イベントハンドラ内では以下の処理を行います。

OpenNextFrame(100)メソッドで、KinectからRGBデータの次のフレームを開きます。
次のフレームがなかった場合のタイムアウトを100ミリセコンドと指定しています。
同様に、次のフレームの距離カメラのストリームを開きます。次のフレームがなかった場合のタイムアウトを100ミリセコンドと指定しています。
背景をマスクし距離データを取得するAppearPlayerプロシージャを実行します。
引数として、RGBと距離カメラで取得した次のフレーム(colorFrameとdepthFrame)を渡しています。

DataContextプロパティにMainWindow自身のインスタンスを渡します。この処理を行わないとプレイヤーが表示されませんので注意してください。

  Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    If KinectSensor.KinectSensors.Count = 0 Then
      MessageBox.Show("KINECTが接続されておりません。")
      Exit Sub
    Else
      kinect = KinectSensor.KinectSensors(0)
      kinect.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30)
      kinect.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30)
      kinect.SkeletonStream.Enable()
 
      Dim myDepthStream As DepthImageStream = kinect.DepthStream
      Dim myColorStream As ColorImageStream = kinect.ColorStream
      myDepthPixelData = New Short(myDepthStream.FramePixelDataLength - 1) {}
      myColorPixelData = New Byte(myColorStream.FramePixelDataLength - 1) {}
 
      Person = New WriteableBitmap(myDepthStream.FrameWidth, myDepthStream.FrameHeight, 96, 96, PixelFormats.Bgra32, Nothing)
      myImageRect = New Int32Rect(0, 0, CInt(Math.Ceiling(Person.Width)), CInt(Math.Ceiling(Person.Height)))
      kinect.Start()
      AddHandler CompositionTarget.Rendering, Sub(renderSender As Object, renderArgs As EventArgs)
        Using colorFrame As ColorImageFrame = kinect.ColorStream.OpenNextFrame(100)
          Using depthFrame As DepthImageFrame = kinect.DepthStream.OpenNextFrame(100)
            AppearPlayer(colorFrame, depthFrame)
          End Using
        End Using
                         End Sub
      DataContext = Me 'この記述がないと人物が表示されない
    End If
  End Sub
  • Kinectで距離カメラの値を取得して、距離に応じて姿を隠すサンプル

薬師寺国安事務所

薬師寺国安事務所代表。Visual Basic プログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。1997年に薬師寺聖とコラボレーション・ユニット PROJECT KySS を結成。2003年よりフリーになり、PROJECT KySS の活動に本格的に参加、.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。Windows Phoneアプリ開発を経て、現在はWindows ストア アプリを多数公開中

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています