Kinect for Windows v2でプロ生ちゃんとベストショットを撮る方法 2014-07-17
先日の記事でも書きましたが、v2からは手の関節もトラッキングできるようになったため、「グー・チョキ・パー」も判別できるようになりました。
というわけで、FaceTracking機能と組み合わせて、「被写体が笑っている」かつ「どちらか一方の手がピースしている」時に写真を撮るサンプルを簡単に作成してみました。
またキャプチャした情報から被写体のみを抽出し、別の画像と合成してpngに出力してくれます。これをもう少し改良すれば、いつでもベストショットで写真が取れるようになるかも…?
FaceTrackingに関して ボーンを取得・描画、それから被写体の抽出はほとんどサンプルと同様です。
今回はデフォルトのサンプルにはなかったFaceTrackingに関して説明します。
FaceTrackingの開始 FaceTrackingを開始するには、まずどの対象をトラッキングするかを設定する必要があります。そこで、BodyFrameからBodyを取得した際にTrackingIdというプロパティがありますので、それを用いてインスタンスを作成しています。
FaceTrackingの開始(VB) 1
2
3
4
5
6
7
Me .faceSource = New FaceFrameSource(Me .kinectSensor) With {
.FaceFrameFeatures = FaceFrameFeatures.Happy,
.TrackingId = body.TrackingId}
Me .faceReader = Me .faceSource.OpenReader
AddHandler Me .faceReader.FrameArrived, AddressOf OnFaceFrameArrived
AddHandler Me .faceSource.TrackingIdLost, AddressOf OnTrackingLost
FaceTrackingの開始(C#) 1
2
3
4
5
6
this .faceSource = new FaceFrameSource(this .kinectSensor) {
FaceFrameFeatures = FaceFrameFeatures.Happy,
TrackingId = body.TrackingId};
this .faceReader = this .faceSource.OpenReader();
this .faceReader.FrameArrived += OnFaceFrameArrived();
this .faceSource.TrackingIdLost += OnTrackingLost();
FaceFrameFeaturesには他にも以下のような項目があります。複数指定することも可能です。
BoundingBoxInColorSpace BoundingBoxInInfraredSpace FaceEngagement Glasses Happy LeftEyeClosed LookingAway MouthMoved MouthOpen PointsInColorSpace PointsInInfraredSpace RightEyeClosed RotationOrientation Trackingデータの処理 無事にTrackingが成功すると、FrameArrivedイベントが発生します。(上記のコードでは、OnFaceFrameArrivedイベントハンドラが呼ばれています)この引数には結果が格納されています。
FaceFrameFeaturesの項目に関してはFacePropertiesプロパティで取得可能です。結果にはYes,Maybe,No,Unknown が返ってきます。
Trackingデータの処理(VB) 1
2
3
4
5
6
7
8
9
10
11
12
Private Sub OnFaceFrameArrived (sender As Object , e As FaceFrameArrivedEventArgs)
Dim faceFrame = e.FrameReference.AcquireFrame
If faceFrame IsNot Nothing Then
Dim result = faceFrame.FaceFrameResult.FaceProperties(FaceProperty.Happy)
If result = DetectionResult.Yes Or result = DetectionResult.Maybe Then
CreateSnapShot()
End If
End If
End Sub
Trackingデータの処理(C#) 1
2
3
4
5
6
7
8
9
10
11
private void OnFaceFrameArrived(Object sender,FaceFrameArrivedEventArgs e)
{
var faceFrame = e.FrameReference.AcquireFrame();
if (faceFrame != null )
{
var result = faceFrame.FaceFrameResult.FaceProperties(FaceProperty.Happy);
if (result == DetectionResult.Yes || result == DetectionResult.Maybe)
CreateSnapShot();
}
}
今回作成したプログラムは、条件が揃った際にスナップショットを作成しますが、その際一瞬にして同じような画像が大量に保存されてしまうことを防ぐため、この仕組みを用いて1トラッキングにつき1回までしか作成しないよう制限 しています。(つまり「画面に写っている人が写真を撮ったら、その人が画面の外に出てもう一度中に入るなどをしてトラッキングを失わない限り、写真を撮らない」、ということを行っています)
Tracking対象を失ってしまった時の処理 画面外に移動した等の理由で対象を失ってしまった際には、TrackingIdLostイベントが発生します。(上記のコードでは、OnTrackingLostイベントハンドラが呼ばれています)
このイベントハンドラが取る引数eに、失ったTrackingId等が格納されているので、それを見て判別することが可能です。
対象を失ってしまった時の処理 1
2
3
4
5
6
7
8
Private Sub OnTrackingLost (sender As Object , e As TrackingIdLostEventArgs)
Console.WriteLine(e.TrackingId)
Me .faceReader = Nothing
Me .faceSource = Nothing
End Sub
1
2
3
4
5
6
7
private void OnTrackingLost(Object sender,TrackingIdLostEventArgs e)
{
Console.WriteLine(e.TrackingId);
this .faceReader = null ;
this .faceSource = null ;
}
注意事項 実はこれだけではプログラムは動かず、分析のためのデータベースが必要となります。(それがないと、Noという結果しか出ません)
そこで、ビルド後のアクションにNUIDatabaseを出力フォルダにコピーするコマンドが実行されるよう、設定する必要があります。
ビルド後のアクション 1
xcopy "C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0\ExtensionSDKs\Microsoft.Kinect.Face\2.0\Redist\CommonConfiguration\x64\NuiDatabase" "NuiDatabase" /e /y /i /r
サンプル 動作画面のサンプルを以下に掲載します。(一人暮らしで家が狭いため、障害物も多く全身が入りきっていません)
右手でピースをした時に反応している パーでは何も反応しない 笑うとHappyとして認識される 笑いながらピースで記念撮影 このような画像が保存されます コード 以下のページで公開しています。基本的にボーンの作成等はサンプルと同様ですので、そちらを見たほうがよいでしょう。
GitHub – KinectCameraSample
また今回背景の画像は プログラミング生放送勉強会 よりプロ生ちゃん を使用させていただきました。(許可は頂いております)
可愛い女の子とベストショットで写真を撮ることができるなんて、まるで夢のようですね!