人物特定に使える!?実際の映像で顔を認識するKinectプログラム

2012年10月5日(金)
薬師寺 国安

RGBカメラ、距離カメラ、スケルトンフレームが更新された時に発生するイベント

e.OpenColorImageFrameで、新しいフレームのRGBカメラの情報を取得し、e.OpenDepthImageFrameで、新しいフレームの距離カメラの情報を取得します。これらのメソッドで取得するcolorImagerFrameやdepthImageFrameは、Usingで括るか、明示的にDisposeする必要があります。Kinect センサーを取得します。

ブール型の変数haveNewFormat変数を宣言し、未定義に設定されていたRGBカメラのイメージフォーマットが、RGBカメラのイメージフレームのフォーマットと同じでない場合のブール値を取得します。ブール値がTrueの場合は、RGBカメラのイメージフォーマットをRGBカメラのイメージフレームのフォーマットと同じにします。バイト配列変数colorImageDataにRGBカメラのイメージフレームのピクセルデータを取得するためのバイト列(colorImageFrame.PixelDataLength - 1で取得)を確保します。

次に、WriteableBitmapクラス型のcolorImageWritableBitmapを下記の書式で初期化します。

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

「ビットマップのピクセルフォーマット」に指定する、PixelFormats.Bgr32は、Bgr32 ピクセル形式を取得します。Bgr32 ピクセル形式を取得します。Bgr32 は、bits per pixel(BPP)が 32 の sRGB 形式です。各カラー チャネル(青、緑、および赤)に割り当てられる bits per pixel(BPP)は 8 です。

ここは、
colorImageWritableBitmap = New WriteableBitmap(640,480, 96, 96, PixelFormats.Bgr32, Nothing)
と指定しても同じです。colorImageというNameのImageコントロールのSourceプロパティにcolorImageWriteableBitmapオブジェクトを指定します。

colorImageFrame.CopyPixelDataToメソッドを呼び出し、バイト列のcolorImageDataからピクセルデータを取得します。CopyPixelDataToメソッドは、ピクセルデータの長さを使用して、事前に割り当てられた配列へ、ピクセルごとの深度データやRGBデータをコピーします。

Kinectの画像をビットマップデータに書き出します。WriteableBitmap型の変数colorImageWritableBitmapにWritePixelsメソッドで、byteからビットマップへ書き出します。ビットマップの指定した領域内のピクセルを更新します。書式は下記の通りです。

WritePixels(更新するWriteableBitmapの四角形,ビットマップの更新に使用するピクセル配列,pixel内の更新領域のストライド,入力バッファのオフセット)

「更新するWriteableBitmapの四角形」には

New Int32Rect(0, 0, colorImageFrame.Width, colorImageFrame.Height)
と指定します。

「pixel内の更新領域のストライド」には、
colorImageFrame.Width * Bgr32BytesPerPixelは640*4=2560に同じです。
と指定します。これは下記のように記述しても同じです。
colorImageWritableBitmap.WritePixels(New Int32Rect(0, 0, 640, 480), colorImageData, 2560, 0)

この記述で、実写のプレイヤーの顔に、顔の輪郭に沿って三角形の集合体のジオメトリーが表示されます。この記述がないと、背景が真っ黒で三角形のジオメトリーで構成された輪郭だけが表示されます。前回と同じ表示になります。

  Private Sub KinectSensorOnAllFramesReady(sender As Object, e As AllFramesReadyEventArgs)
    Using colorImageFrame =e.OpenColorImageFrame()
      Using depthImageFrame = e.OpenDepthImageFrame
        Dim kinect As KinectSensor = TryCast(sender, KinectSensor)
        If kinect Is Nothing = True Then
          Return
        End If
   
        If colorImageFrame Is Nothing = True Then
          Return
        End If
        Dim haveNewFormat As Boolean = currentColorImageFormat <> colorImageFrame.Format
        If haveNewFormat = True Then
          currentColorImageFormat = colorImageFrame.Format
          colorImageData = New Byte(colorImageFrame.PixelDataLength - 1) {}
          colorImageWritableBitmap = New WriteableBitmap(colorImageFrame.Width, colorImageFrame.Height, 96, 96, PixelFormats.Bgr32, Nothing)
          colorImage.Source = colorImageWritableBitmap
        End If
        colorImageFrame.CopyPixelDataTo(colorImageData)
        colorImageWritableBitmap.WritePixels(New Int32Rect(0, 0, colorImageFrame.Width, colorImageFrame.Height), colorImageData, colorImageFrame.Width * Bgr32BytesPerPixel, 0)
      End Using
    End Using
  End Sub

ウィンドウが閉じられた時の処理

Kinectセンサーの検出を停止します。ユーザーコントロールであるFaceTrackingViewer1のリソースを解放します。

  Private Sub MainWindow_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles Me.Closing
    sensorChooser.Stop()
    FaceTrackingViewer1.Dispose()
  End Sub
End Class

以上で今回のサンプルは終了です。

  • 実際の映像で顔を認識する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メルマガ会員のサービス内容を見る

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