使用kinect计算被跟踪物体的质心



我正在为我的研究项目开发Kinect。我以前曾计算运动学的关节角度和关节坐标。我想计算被跟踪物体的质心。任何想法都将不胜感激,代码片段将非常有用。如果没有社区的帮助,我不可能做这样的事情,这在很大程度上要归功于堆栈溢出。提前感谢请找到我想包含这个质心函数的代码。此函数用于跟踪骨骼。

Skeleton GetFirstSkeleton(AllFramesReadyEventArgs e){使用(SkeletonFrame skeletonFrameData=e.OpenSkeletonFrame()){if(skeletonFrameData==null){返回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 allSkelete=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(数据中的关节。关节)

{
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. http://mathwiki.ucdavis.edu/Calculus/Vector_Calculus/Multiple_Integrals/Moments_and_Centers_of_Mass#Three-尺寸标注_实体
  2. http://www.slideshare.net/GillianWinters/center-of-mass-presentation
  3. http://en.wikipedia.org/wiki/Locating_the_center_of_mass

基本上,不管怎样,你都需要找到你的用户数量。这可以是一个简单的输入,然后你可以确定一个人每只脚的重量,并使用所有这些来源描述的方程。另一种选择可能是在二维用户的平面形状表示上使用铅垂线,但这并不是真正准确的三维质心。

下面是一个如何计算每只脚上质量的例子。使用上的公式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生成的自动平面。

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

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点。

最新更新