2

MS Kinect のリアルタイム戦略制御スキームを実装しようとしています。これまでのところ、左手を動かすことで動かすことができるカーソルがあります (利き手に応じて右に動かすこともできます)。プレイヤーの動きのスケルトンを設定し、手首、肘、肩、体の中心の座標をアプリケーションに提供する Open-NI ベースの Kinect コントローラーを用意しました。これらの手首座標を画面に投影するために、プレイヤーの中心からわずかに左/右に位置する Rectangle を設定しました。手首が四角形の内側を移動する限り、カーソルは画面上を移動します。私の問題は、XNA-Rectangle が原点として左上隅を持っていることです。つまり、X 軸は「あるべき」ように右を指しますが、Y 軸は下を指し、Kinect の Y 軸は -座標系は上向き。これにより、手を下に動かすとカーソルが画面上で上に移動し、その逆も同様です。Kinect 座標系で何かを変更する方法はありません。長方形の「座標系」を「反転」して、Y 軸が上になるようにすることはできますか?

関連するコードは次のとおりです。

(Calibrate()-メソッドから:)

List<Vector3> joints = UDPlistener.getInstance().ParseCalibCoordinates(data);
//0 = Right Wrist 1 = Right Elbow 2 = Right Shoulder
//3 = Left Wrist  4 = Left Elbow 5 = Left Shoulder
//6 = Center
height = 762; 
width = 1024;            
switch (hand)
{
    case 0:
    cursorSpace = new Rectangle((int)(joints[6].X * 2) - 200, (int)(joints[6].Y * 2) + height, width, height);
    break;
    case 3:
    cursorSpace = new Rectangle((int)(joints[6].X * 2) - 1200, (int)(joints[6].Y * 2) + height, width, height);
    break;
}

public Point Cursor(String data)
{   
    List<Vector3> joints = UDPlistener.getInstance().ParsePlayCoordinates(data);
    //0 = Right Wrist 1 = Left Wrist 2 = Center
    double mhx = 0; //main hand x-coordinate
    double mhy = 0; // main hand y-coordinate
    switch (hand)
    {
        case 0:
        mhx = joints[hand].X;
        mhy = joints[hand].Y;
        break; 

        case 3:
        mhx = joints[hand-2].X;
        mhy = joints[hand-2].Y;
        break;                    
    }

int x; 
int y;
if (Math.Abs(mhx - mhxOld) < 1.0 || Math.Abs(mhy - mhyOld) < 1.0) 
//To remove jittering of the cursor
{
    x = (int) mhxOld * 2;
    y = (int) mhyOld * 2;  
}
else
{
    x = (int) mhx * 2;
    mhxOld = mhx;
    y = (int) mhy * 2;
    mhyOld = mhy;
}

Point cursor = new Point(0,0);

if (cursorSpace.Contains(x,y)) 
{
    cursor = new Point(x - cursorSpace.X, y - CursorSpace.Y);                    
    lastCursorPos = cursor;
    return cursor;                    
}

テキストの壁で申し訳ありませんが、私は自分自身を明確にすることができれば幸いです.

前もって感謝します、

株式会社

4

2 に答える 2

2

OpenNI 座標の変換には拡張メソッドを使用します。次の例では、Vector2 オブジェクトとして表される、左上隅の 640x480 の長方形で、OpenNI 座標を XNA 座標にマップします。

public static Vector2 ToXnaCoordinates(this Point3D point)
{
    return new Vector2(
        point.X + 320,
        (point.Y - 240) * -1);
}

y座標を反転させる魔法がその* -1部分です。

640x480 以外のサイズの長方形に到達する場合は、変換後にそれに応じて座標をスケーリングする必要があります。例:

public static Vector2 ToScaledXnaCoordinates(this Point3D point, int rectSizeX, int rectSizeY)
{
    return new Vector2(
        (point.X + 320) * rectSizeX / 640,
        (point.Y - 240) * -rectSizeY / 480);
}
于 2012-07-19T11:26:40.337 に答える
0

これが XNA ではないことはわかっていますが、これらの wpf ユーザーのためにこれを公開したかったのです :) Channel 9 のアプローチのようなものを使用している場合は、ブール値を使用して、反転されているかどうかを判断してください。例:

    private void ScalePosition(FrameworkElement element, Joint joint, bool inverted)
    {
        //convert the value to X/Y
        Joint scaledJoint = joint.ScaleTo(967, 611);

        //convert & scale (.3 = means 1/3 of joint distance)
        //Joint scaledJoint = joint.ScaleTo(1280, 720, 1f, 1f);
        if (!inverted)
        {
            Canvas.SetLeft(element, scaledJoint.Position.X);
            Canvas.SetTop(element, scaledJoint.Position.Y);
        }

        if (inverted)
        {
            Canvas.SetLeft(element, scaledJoint.Position.X);
            Canvas.SetBottom(element, scaledJoint.Position.Y);
        }
    }

これがWPFユーザーに役立つことを願っています!

于 2012-07-23T14:35:40.873 に答える