使用kinect计算被跟踪的身体质量中心?

时间:2014-02-23 19:48:04

标签: kinect kinect-sdk

我正在研究Kinect的研究项目。我以前曾工作过来计算kinect和关节坐标的关节角度。我想计算被跟踪的身体的质心。 任何想法都将受到赞赏,代码片段将非常有用。 我欠了很多堆栈溢出而没有社区帮助它不可能做这样的事情。 提前致谢 请找到我想要包含此质量功能中心的代码。此功能跟踪骨架。

Skeleton GetFirstSkeleton(AllFramesReadyEventArgs e)         {             使用(SkeletonFrame skeletonFrameData = e.OpenSkeletonFrame())             {                 if(skeletonFrameData == null)                 {                     return 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(skeletonFrame.Skeletons中的SkeletonData数据){

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 select s).Count();

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

            int totalSkeletons = numberOfSkeletonsP + numberOfSkeletonsT;

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

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

if(data.TrackingState == SkeletonTrackingState.PositionOnly)

            {

foreach(数据中的联合关系.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 );

                    }

            }

1 个答案:

答案 0 :(得分:0)

在这里查看几个资源:

  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
  4. 基本上无论如何,您都需要找到用户的质量。这可以是一个简单的输入,然后您可以确定每个人放置多少重量并使用所有这些来源中描述的等式。另一种选择可能是在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点的情节来显示这一点。