2014-02-23 70 views
0

我正在为我的研究项目开发Kinect。之前我曾经工作过,计算了kinect和关节坐标的关节角度。我想计算正在跟踪的身体的质心。 任何想法将不胜感激,代码片段将非常有帮助。 如果没有社区的帮助,我很多都会遇到堆栈溢出问题,因此无法做到这一点。 在此先感谢 请找到我想要包含此质量函数中心的代码。该功能跟踪骨架。使用kinect计算正在跟踪的身体质量中心?

骨架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(在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 

where 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); 

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

如果(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); 

        } 

      } 

回答

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

基本上无论什么时候,你会需要找到自己的用户的质量。这可以是一个简单的输入,然后您可以确定该人每只脚放置多少重量,并使用所有这些来源中描述的方程式。另一种选择可能是在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点。

+0

感谢您的反馈。我可能听起来是这个案子的新手,但我们如何确定每个人脚上的重量,因为kinect只允许我们跟踪,而不是衡量体重。另一个问题是如何将其包含在我的代码中。请帮助我编写Mass中的这个中心代码片段。先谢谢您的帮助。 – user2823510

+0

@ user2823510检查编辑,你仍然必须编写自己的批量代码,但这应该让你开始 –

+0

嘿Outlaw狐猴,谢谢你提供了一个伟大的洞察力,它应该如何工作来计算质量。 – user2823510