読者です 読者をやめる 読者になる 読者になる

Natural Software

KinectなどのDepthセンサーを中心に活動しています

関節の向きを利用する

Kinect


Kinect for Windows SDK v1.5から関節の向きが利用できるようになりました。
このあたりはよくわからないのですが、ここをやりながら試行錯誤しています。
間違いなどあれば突っ込みいただけると嬉しいです^^;


単純にしてみたので、要所の部分だけまとめます。
コードはここに載せてあります。

関節の角度

関節の角度は、Skeletonクラスに追加されています(Jointのパラメーターではないんですね)。
BoneOrientationCollectionというクラスで追加されており、JointCollectionと同じように、必要な関節(JointType)を指定することで、その関節の角度を取得することができます。
個別の関節の角度はBoneOrientationクラスで定義されており、メンバは次のようになっています。
#関節と関節(骨)の角度という意味合いでしょうか

フィールド名 意味
AbsoluteRotation 関節の角度
HierarchicalRotation ??
EndJoint 終点の骨格
StartJoint 始点の骨格


角度の取得にはAbsoluteRotationと使用し、これはBoneRotationクラスとして定義されています。BoneRotationクラスのメンバは次の通りです。

フィールド名 意味
Matrix 関節の角度を示す行列
Quaternion クォータニオン

クォータニオンはよく聞くのですが、理解できてないので説明できません^^;
角度の変換にはMatrixを使います。MatrixはMatrix4クラスとして定義されており、4x4の行列です。


WPFを使って図形を回転させるにはMatrixという2x2の行列クラスがSystem.Windows.Media名前空間に定義されていますので、それにあてはめ回転させます。

顔に位置に矩形を置き、それを顔の向きで回転させるコード

最後に要点部分のコードを載せておきます。

/// <summary>
/// 顔の位置で四角形を回転させる
/// </summary>
/// <param name="skeleton"></param>
private void RotateRectangle( Skeleton skeleton )
{
    var head = skeleton.Joints[JointType.Head];
    if ( head.TrackingState != JointTrackingState.NotTracked ) {
        // 四角を移動させる
        var point = kinect.MapSkeletonPointToColor( head.Position, kinect.ColorStream.Format );
        rectFace.Margin = new Thickness( point.X - (rectFace.Width / 2),
                                            point.Y - (rectFace.Height / 2), 0, 0 );

        // 四角を回転させる
        var headMatrix = skeleton.BoneOrientations[JointType.Head].AbsoluteRotation.Matrix;

        Matrix matrix = new Matrix( -headMatrix.M11, headMatrix.M12,
                                    -headMatrix.M21, headMatrix.M22,
                                    0, 0 );

        rectFace.RenderTransform = new MatrixTransform( matrix );
    }
}