人物特定に使える!?実際の映像で顔を認識するKinectプログラム(3ページ目)
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
以上で今回のサンプルは終了です。