【问题标题】:Calculating Center of mass of body being tracked using kinect?计算使用kinect跟踪的身体质量中心?
【发布时间】:2014-02-23 19:48:03
【问题描述】:

我正在为我的研究项目开发 Kinect。我以前曾计算过 kinect 的关节角度和关节坐标。我想计算被跟踪的身体的质心。 任何想法都将不胜感激,并且代码 sn-ps 将非常有帮助。 如果没有社区的帮助,我对堆栈溢出负有很多责任,这是不可能做这样的事情的。 提前致谢 请找到我想要包含此质心功能的代码。该函数跟踪骨架。

骨架 GetFirstSkeleton(AllFramesReadyEventArgs e) { 使用 (SkeletonFrame skeletonFrameData = e.OpenSkeletonFrame()) { 如果(skeletonFrameData == null) { 返回空值; }

            skeletonFrameData.CopySkeletonDataTo(allSkeletons);

            //get the first tracked skeleton
            Skeleton first = (from s in allSkeletons
                              where s.TrackingState == SkeletonTrackingState.Tracked
                              select s).FirstOrDefault();
            return first;
        }

我已经尝试在我的代码中使用此代码,但它不习惯,谁能帮我包括质量中心代码。

oreach(skeletonData 中的skeletonFrame.Skeletons 数据){

SkeletonFrame allskeleton = e.SkeletonFrame;

            // Count passive and active person up to six in the group  

            int numberOfSkeletonsT = (from s in allskeleton.Skeletons

                                      where s.TrackingState == SkeletonTrackingState.Tracked  select s).Count();

            int numberOfSkeletonsP = (from s in allskeleton.Skeletons  

其中 s.TrackingState == SkeletonTrackingState.PositionOnly 选择 s).Count();

            // Count passive and active person up to six in the group

            int totalSkeletons = numberOfSkeletonsP + numberOfSkeletonsT;

            //Console.WriteLine("TotalSkeletons = " + totalSkeletons);

//============================================== =========

如果(data.TrackingState == SkeletonTrackingState.PositionOnly)

            {

foreach(data.Joints 中的关节)

                {

                    if (joint.Position.Z != 0)

                    {

double centerofmassX = com.Position.X;

                        double centerofmassY = com.Position.Y;

                        double centerofmassZ = com.Position.Z;

   Console.WriteLine( centerofmassX +  centerofmassY + centerofmassZ );

                    }

            }

【问题讨论】:

    标签: kinect kinect-sdk


    【解决方案1】:

    在此处查看一些资源:

    1. http://mathwiki.ucdavis.edu/Calculus/Vector_Calculus/Multiple_Integrals/Moments_and_Centers_of_Mass#Three-Dimensional_Solids
    2. http://www.slideshare.net/GillianWinters/center-of-mass-presentation
    3. http://en.wikipedia.org/wiki/Locating_the_center_of_mass

    基本上无论如何,您都需要找到大量用户。这可以是一个简单的输入,然后您可以确定该人每只脚承受的重量,并使用所有这些来源中描述的方程式。另一种选择可能是在 2D 用户的平面形状表示上使用 plumb lines,但这不会是实际准确的 3D 质心。

    下面是一个示例,说明如何计算每只脚的质量。使用http://www.vitutor.com/geometry/distance/line_plane.html上的公式

    Vector3 v = new Vector3(skeleton.Joints[JointType.Head].Position.X,    skeleton.Joints[JointType.Head].Position.Y, skeleton.Joints[JointType.Head].Position.Z);
    double mass;
    double leftM, rightM;
    
    double A = sFrame.FloorClipPlane.X,
    B = sFrame.FloorClipPlane.Y,
    C = sFrame.FloorClipPlane.Z;
    
    //find angle
    double angle = Math.ASin(Math.Abs(A * v.X + B * v.Y * C * v.Z)/(Math.Sqrt(A * A + B * B + C * C) * Math.Sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z)));
    
    if (angle == 90.0)
    {
         leftM = mass / 2.0;
         rightM = mass / 2.0;
    }
    
    double distanceFrom90 = 90.0 - angle;
    
    if (distanceFrom90 > 0)
    {
        double leftMultiple = distanceFrom90 / 90.0;
        leftM = mass * leftMultiple;
        rightM = mass - leftM;
    }
    
    else
    {
        double rightMultiple = distanceFrom90 / 90.0;
        rightM = rightMultiple * mass;
        leftM = mass - rightMultiple;
    }
    

    这当然是假设用户双脚站立,但您可以修改代码以根据用户的脚创建一个新平面,而不是 Kinect 生成的自动平面。

    然后找到质心的代码,您必须选择一个基准。我会选择头部,因为那是人的顶部,你可以很容易地从它身上测量下来。使用here找到的步骤:

    double distanceFromDatumLeft = Math.Sqrt(Math.Pow(headX - footLeftX, 2) + Math.Pow(headY - footLeftY, 2) + Math.Pow(headZ - footLeftZ, 2));
    double distanceFromDatumLeft = Math.Sqrt(Math.Pow(headX - footRightX, 2) + Math.Pow(headY - footRightY, 2) + Math.Pow(headZ - footRightZ, 2));
    
    double momentLeft = distanceFromDatumLeft * leftM;
    double momentRight = distanceFromDatumRight * rightM;
    
    double momentSum = momentLeft + momentRight;
    
    //measured in units from the datum
    double centerOfGravity = momentSum / mass;
    

    然后,您当然可以通过将点传递给绘图,该点位于头部下方 centerOfGravity 点,从而在屏幕上显示这一点。

    【讨论】:

    • 感谢您的反馈。对于这种情况,我可能听起来很新手,但我们如何确定人每只脚上的重量,因为 kinect 只允许我们跟踪,而不是测量重量。另一个问题是如何将它包含在我的代码中。请帮助我在存在的第一个代码 sn-p 中对这个质量中心进行编码。提前感谢您的帮助。
    • @user2823510 检查编辑,您仍然需要自己编写批量代码,但这应该可以帮助您开始
    • 嘿Outlaw Lemur,感谢您提供了一个很好的见解,它应该如何计算质量。
    • Outlaw Lemur 你真是太棒了,有这么多的逻辑和帮助。我能再问你一件事吗。我有这个 Kinect 相机正在运行,它能够计算主体骨骼的关节角度.但是当我尝试通过将 kinect 相机放在用户一侧(特别是左侧或右侧,你可以考虑任何)来计算关节角度时,问题就开始了,我在使用相同的算法和代码后获得的数据从侧视相机计算我得到的值被搞砸了。作为用户面前的 Kinect,它没有给出正确的值
    • @user2823510 首先,如果我帮助了你,我很高兴,你可以接受这个答案:)...其次,请参阅stackoverflow.com/questions/10192476/… 你可以看到侧向骨骼跟踪不适用于 Kinect
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多