如何将kinect骨架移动到另一个位置

时间:2012-11-25 15:44:48

标签: kinect kinect-sdk

我正在研究一种扩展方法,将一个骨架移动到kinect字段视图中的所需位置。

我的代码接收要移动的骨架和命运位置,我计算接收的骨架髋关节中心和命运位置之间的距离以找到how much to move,然后应用此因子的联合中的迭代。我的代码,实际上看起来像这样。

public static Skeleton MoveTo(this Skeleton skToBeMoved, Vector4 destiny)
    {
        Joint newJoint = new Joint();

        ///Based on the HipCenter (i dont know if it is reliable, seems it is.)
        float howMuchMoveToX = Math.Abs(skToBeMoved.Joints[JointType.HipCenter].Position.X - destiny.X);
        float howMuchMoveToY = Math.Abs(skToBeMoved.Joints[JointType.HipCenter].Position.Y - destiny.Y);
        float howMuchMoveToZ = Math.Abs(skToBeMoved.Joints[JointType.HipCenter].Position.Z - destiny.Z);
        float howMuchToMultiply = 1;

        // Iterate in the 20 Joints
        foreach (JointType item in Enum.GetValues(typeof(JointType)))
        {
            newJoint = skToBeMoved.Joints[item];

            // This adjust, try to keeps the skToBeMoved in the desired position
            if (newJoint.Position.X < 0)
                howMuchToMultiply = 1; // if the point is in a negative position, carry it to a "more positive" position
            else
                howMuchToMultiply = -1; // if the point is in a positive position, carry it to a "more negative" position

            // applying the new values to the joint
            SkeletonPoint pos = new SkeletonPoint()
            {
                X = newJoint.Position.X + (howMuchMoveToX * howMuchToMultiply),
                Y = newJoint.Position.Y, // * (float)whatToMultiplyY,
                Z = newJoint.Position.Z, // * (float)whatToMultiplyZ
            };

            newJoint.Position = pos;
            skToBeMoved.Joints[item] = newJoint;

            //if (skToBeMoved.Joints[JointType.HipCenter].Position.X < 0)
            //{
            //    if (item == JointType.HandLeft)
            //    {
            //        if (skToBeMoved.Joints[item].Position.X > 0)
            //        {

            //        }
            //    }
            //}
        }

        return skToBeMoved;
    }

Actualy,只考虑X位置。

现在,问题:

如果我站在负面位置,并将我的手移到正面位置,那就有一种奇怪的行为,看看这个图像

enter image description here

要重现此行为,您可以使用此代码

using (SkeletonFrame frame = e.OpenSkeletonFrame())
        {
            if (frame == null)
                return new Skeleton();

            if (skeletons == null || skeletons.Length != frame.SkeletonArrayLength)
            {
                skeletons = new Skeleton[frame.SkeletonArrayLength];
            }
            frame.CopySkeletonDataTo(skeletons);

            Skeleton skeletonToTest = skeletons.Where(s => s.TrackingState == SkeletonTrackingState.Tracked).FirstOrDefault();

            Vector4 newPosition = new Vector4();
            newPosition.X = -0.03412333f;
            newPosition.Y = 0.0407479f;
            newPosition.Z = 1.927342f;
            newPosition.W = 0; // ignored

            skeletonToTest.MoveTo(newPosition);
        }

我知道,这是简单的数学,但我无法弄清楚为什么会发生这种情况。 任何帮助都会被贬低。

1 个答案:

答案 0 :(得分:9)

问题解决了。这是代码

public static Skeleton MoveTo(this Skeleton skToBeMoved, Vector4 destiny)
    {
        Joint newJoint = new Joint();

        ///Based on the HipCenter (i dont know if it is reliable, seems it is.)
        float howMuchMoveToX = (skToBeMoved.Joints[JointType.HipCenter].Position.X - destiny.X) * -1;
        float howMuchMoveToY = (skToBeMoved.Joints[JointType.HipCenter].Position.Y - destiny.Y) * -1;
        float howMuchMoveToZ = (skToBeMoved.Joints[JointType.HipCenter].Position.Z - destiny.Z) * -1;

        // Iterate in the 20 Joints
        foreach (JointType item in Enum.GetValues(typeof(JointType)))
        {
            newJoint = skToBeMoved.Joints[item];

            // applying the new values to the joint
            SkeletonPoint pos = new SkeletonPoint()
            {
                X = (float)(newJoint.Position.X + (howMuchMoveToX)),
                Y = (float)(newJoint.Position.Y + (howMuchMoveToY)),
                Z = (float)(newJoint.Position.Z + (howMuchMoveToZ))
            };

            newJoint.Position = pos;
            skToBeMoved.Joints[item] = newJoint;
        }

        return skToBeMoved;
    }
相关问题