Kinect骨架缩放异常行为 [英] Kinect skeleton Scaling strange behaviour

查看:108
本文介绍了Kinect骨架缩放异常行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试缩放一个骨架以匹配另一个骨架的尺寸. 我的算法执行以下操作:

I am trying to scale a skeleton to match to the sizes of another skeleton. My algoritm do the following:

  • 使用植物塔里木(Tetagorean teorem)查找起源骨骼和命运骨骼两个关节之间的距离
  • 将这两个距离相除即可找到一个乘数.
  • 将每个关节乘以该因子.

这是我的实际代码:

public static Skeleton ScaleToMatch(this Skeleton skToBeScaled, Skeleton skDestiny)
    {
        Joint newJoint = new Joint();

        double distanciaOrigem = 0;
        double distanciaDestino = 0;
        double fator = 1;
        SkeletonPoint pos = new SkeletonPoint();

        foreach (BoneOrientation bo in skToBeScaled.BoneOrientations)
        {
            distanciaOrigem = FisioKinectCalcs.Distance3DBetweenJoint(skToBeScaled.Joints[bo.StartJoint], skToBeScaled.Joints[bo.EndJoint]);
            distanciaDestino = FisioKinectCalcs.Distance3DBetweenJoint(skDestiny.Joints[bo.StartJoint], skDestiny.Joints[bo.EndJoint]);

            if (distanciaOrigem > 0 && distanciaDestino > 0)
            {
                fator = (distanciaDestino / distanciaOrigem);

                newJoint = skToBeScaled.Joints[bo.EndJoint]; // escaling only the end joint as the BoneOrientatios starts from HipCenter, i am scaling from center to edges.

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

                newJoint.Position = pos;
                skToBeScaled.Joints[bo.EndJoint] = newJoint;
            }
        }

        return skToBeScaled;
    }

除手脚外,其他所有东西似乎都工作正常

Every seems to work fine except for the hands and foots

看这张图片

我身上有自己的骨骼,骨骼的大小可以缩放到另一个人的大小,但手脚仍然发疯. (但代码看起来正确)

I have my own skeleton over me, and my skeleton scaled to the sizes of another person, but the hands and foots still crazy. (but code looks right)

有什么建议吗?

推荐答案

我建议对因子进行平滑处理,使其通常适合适当的比例.尝试以下代码:

I would suggest to smooth the factor so it generally fits the proper scale. Try this code:

    private static Dictionary<JointType, double> jointFactors = null;
    static CalibrationUtils()
    {
        InitJointFactors();
    }
    public static class EnumUtil
    {
        public static IEnumerable<T> GetValues<T>()
        {
            return Enum.GetValues(typeof(T)).Cast<T>();
        }
    }
    private static void InitJointFactors()
    {
        var jointTypes = EnumUtil.GetValues<JointType>();
        jointFactors = new Dictionary<JointType, double>();
        foreach(JointType type in jointTypes)
        {
            jointFactors.Add(type, 0);
        }
    }
    private static double SmoothenFactor(JointType jointType, double factor, int weight)
    {
        double currentValue = jointFactors[jointType];
        double newValue = 0;
        if(currentValue != 0)
            newValue = (weight * currentValue + factor) / (weight + 1);
        else
            newValue = factor;
        jointFactors[jointType] = newValue;
        return newValue;
    }

当涉及因子使用时,请先使用SmoothenFactor方法:

When it comes to factor usage just use the SmoothenFactor method first:

    public static Skeleton ScaleToMatch(this Skeleton skToBeScaled, Skeleton skDestiny, double additionalFactor = 1)
    {
        Joint newJoint = new Joint();

        double distanceToScale = 0;
        double distanceDestiny = 0;
        double factor = 1;
        int weight = 500;
        SkeletonPoint pos = new SkeletonPoint();
        Skeleton newSkeleton = null;
        KinectHelper.CopySkeleton(skToBeScaled, ref newSkeleton);
        SkeletonPoint hipCenterPosition = newSkeleton.Joints[JointType.HipCenter].Position;
        foreach(BoneOrientation bo in skToBeScaled.BoneOrientations)
        {
            distanceToScale = Distance3DBetweenJoints(skToBeScaled.Joints[bo.StartJoint], skToBeScaled.Joints[bo.EndJoint]);
            distanceDestiny = Distance3DBetweenJoints(skDestiny.Joints[bo.StartJoint], skDestiny.Joints[bo.EndJoint]);

            if(distanceToScale > 0 && distanceDestiny > 0)
            {

                factor = (distanceDestiny / distanceToScale) * additionalFactor;


                newJoint = skToBeScaled.Joints[bo.EndJoint]; // escaling only the end joint as the BoneOrientatios starts from HipCenter, i am scaling from center to edges.

                factor = SmoothenFactor(newJoint.JointType, factor, weight);

                pos = new SkeletonPoint()
                {
                    X = (float)((newJoint.Position.X - hipCenterPosition.X) * factor + hipCenterPosition.X),
                    Y = (float)((newJoint.Position.Y - hipCenterPosition.Y) * factor + hipCenterPosition.Y),
                    Z = (float)((newJoint.Position.Z - hipCenterPosition.Z) * factor + hipCenterPosition.Z)
                };
                newJoint.Position = pos;
                newSkeleton.Joints[bo.EndJoint] = newJoint;
            }
        }
        return newSkeleton;
    }

如您所见,我还修改了您的ScaleToMatch方法.需要相对于HipCenter位置移动关节.另外,新位置也会保存到新的Skeleton实例中,因此不会在进一步的矢量计算中使用它们.

I also modified your ScaleToMatch method as you see. There was a need to move joints in relation to HipCenter position. Also new positions are saved to a new Skeleton instance so they are not used in further vector calculations.

使用weight进行实验,但是由于我们的骨骼长度是恒定的,因此您可以使用100或更大的数字,以确保错误的Kinect读数不会干扰正确的比例.

Experiment with the weight but since our bones length is constant you can use big numbers like 100 and more to be sure that wrong Kinect readings do not disturb the correct scale.

这是如何帮助缩放HandRight关节位置的一个示例:

Here's an example of how it helped with scaling HandRight joint position:

weight被设置为500.生成的factor应该在2左右(因为基本骨架被故意缩小了2倍).

The weight was set to 500. The resulting factor is supposed to be around 2 (because the base skeleton was purposely downscaled by a factor of 2).

希望对您有帮助!

这篇关于Kinect骨架缩放异常行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆