[英]How to track only one person/body with Kinect v2 in C#
我想追踪第一个人,并且只使用这个人的身体。
因此,基本上,当一个人被跟踪,并且有人在他身后行走或与这个人看着时,如果他们移动了,则该kinect不能识别任何其他人。
我正在使用C#中的SDK 2.0“ Body Basics-WPF”形式的示例代码。 我的目标是仅由一个人识别几个关节(成功完成)。 我找到了一个如何在Kinect v1上实现它的线程,但对于Kinect v2则没有。 这里的代码:
private void Reader_FrameArrived(object sender, BodyFrameArrivedEventArgs e)
{
bool dataReceived = false;
using (BodyFrame bodyFrame = e.FrameReference.AcquireFrame())
{
if (bodyFrame != null)
{
if (this.bodies == null)
{
this.bodies = new Body[bodyFrame.BodyCount];
}
bodyFrame.GetAndRefreshBodyData(this.bodies);
dataReceived = true;
}
}
if (dataReceived)
{
using (DrawingContext dc = this.drawingGroup.Open())
{
dc.DrawRectangle(Brushes.Black, null, new Rect(0.0, 0.0, this.displayWidth, this.displayHeight));
int penIndex = 0;
foreach (Body body in this.bodies)
{
Pen drawPen = this.bodyColors[penIndex++];
if (body.IsTracked)
{
this.DrawClippedEdges(body, dc);
IReadOnlyDictionary<JointType, Joint> joints = body.Joints;
Dictionary<JointType, Point> jointPoints = new Dictionary<JointType, Point>();
foreach (JointType jointType in joints.Keys)
{
if (jointType == JointType.ShoulderRight || jointType == JointType.ElbowRight || jointType == JointType.WristRight || jointType == JointType.HandRight ||
jointType == JointType.ShoulderLeft || jointType == JointType.ElbowLeft || jointType == JointType.WristLeft || jointType == JointType.HandLeft)
{
CameraSpacePoint position = joints[jointType].Position;
if (position.Z < 0)
{
position.Z = InferredZPositionClamp;
}
DepthSpacePoint depthSpacePoint = this.coordinateMapper.MapCameraPointToDepthSpace(position);
jointPoints[jointType] = new Point(depthSpacePoint.X, depthSpacePoint.Y);
}
}
this.DrawBody(joints, jointPoints, dc, drawPen);
}
}
this.drawingGroup.ClipGeometry = new RectangleGeometry(new Rect(0.0, 0.0, this.displayWidth, this.displayHeight));
}
}
}
安静一阵子,但我通过自己的功能来跟踪一个人来解决此问题。 如果被跟踪的人离开了“身体阵列”中的下一个顶部,则获取“被跟踪的人”。
private ulong currTrackingId = 0;
private Body GetActiveBody()
{
if (currTrackingId <= 0)
{
foreach (Body body in this.bodies)
{
if (body.IsTracked)
{
currTrackingId = body.TrackingId;
return body;
}
}
return null;
}
else
{
foreach (Body body in this.bodies)
{
if (body.IsTracked && body.TrackingId == currTrackingId)
{
return body;
}
}
}
currTrackingId = 0;
return GetActiveBody();
}
我使用的是较旧的Kinect,但仍然没有新的Kinect,因此这可能行不行:如果bodyFrame.BodyCount会给您面对Kinect的人数,然后将其替换为1,这样您的代码将变为:
this.bodies = new Body [1];
我认为通常kinect会选择最接近的人。 试试看,告诉我你得到了什么。
无需使用foreach来迭代bodys数组,而只需使用列表中的第一个body。
更换:
foreach (Body body in this.bodies)
{
if (body.IsTracked)
{
...
附:
var body = this.bodies[0];
if (body.tracked)
{
...
更新:
我只是使用Kinect Studio进行了尝试,但我发现即使只有一个跟踪主体,也不能保证它位于数组的第一个插槽中。 在我的应用程序中,现在我正在使用LINQ来获取IsTracked == true的第一个正文。 对于生产准备好的代码,我没有很好的答案。 如果我解决了这个问题,我将更新这篇文章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.