如何在 C# 中使用 Kinect v2 仅跟踪一个人/身体

本文关键字:v2 跟踪 一个人 身体 Kinect | 更新日期: 2023-09-27 18:31:16

我想跟踪第一个人,并且只使用这个人的身体。

所以基本上当一个人被跟踪时,有人走在他身后或正在和这个人一起看,如果他们移动,kinect 应该不会识别其他人。

我正在使用 C# 中 SDK 2.0"正文基础知识-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));
            }
        }
    }

如何在 C# 中使用 Kinect v2 仅跟踪一个人/身体

段时间很安静,但我用自己的功能来管理这个问题,以保持一个人的跟踪。如果被跟踪的人离开身体阵列中的下一个顶部身体,则获取"被跟踪的人"。

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.body = new Body[1];

我认为通常 kinect 会选择最接近的人。试试吧,告诉我你得到了什么。

不要使用

foreach 来迭代 body 数组,只需使用列表中的第一个主体。

取代:

foreach (Body body in this.bodies) 
{
   if (body.IsTracked) 
   {
      ...

跟:

var body = this.bodies[0];
if (body.tracked)
{
    ...

更新:

我刚刚使用 Kinect Studio 尝试了这个,我发现即使只有一个跟踪的主体,也不能保证它位于阵列的第一个插槽中。在我的应用程序中,现在我使用 LINQ 获取 IsTrack == true 的第一个正文。关于如何为生产就绪代码执行此操作,我没有很好的答案。如果我解决了这个问题,我会更新这篇文章。