简体   繁体   English

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

[英]How to track only one person/body with Kinect v2 in C#

I would like to track the first person, and use only the body of this person. 我想追踪第一个人,并且只使用这个人的身体。

So basically when one person is tracked, and there are people walking behind him or are looking with this guy, if they move, the kinect shouldn't recognise anyone else. 因此,基本上,当一个人被跟踪,并且有人在他身后行走或与这个人看着时,如果他们移动了,则该kinect不能识别任何其他人。

I am using the sample code form the SDK 2.0 "Body Basics-WPF" in C#. 我正在使用C#中的SDK 2.0“ Body Basics-WPF”形式的示例代码。 My goal is to recognize only a few joints(successfully done) form only one person. 我的目标是仅由一个人识别几个关节(成功完成)。 I've found a thread how you can make it for Kinect v1, but nothing for Kinect v2. 我找到了一个如何在Kinect v1上实现它的线程,但对于Kinect v2则没有。 Here the code: 这里的代码:

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

Quiet a time ago but I manage this Problem with a own Function to Keep one Person tracked. 安静一阵子,但我通过自己的功能来跟踪一个人来解决此问题。 If the tracked Person leave the next top Body in the Body Array get the "Tracked Person". 如果被跟踪的人离开了“身体阵列”中的下一个顶部,则获取“被跟踪的人”。

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();
}

I worked with the older Kinect and still haven't got the new one so this might or might not work: if bodyFrame.BodyCount will just give you the number of people facing the Kinect then replace it with a 1 so your code becomes: 我使用的是较旧的Kinect,但仍然没有新的Kinect,因此这可能行不行:如果bodyFrame.BodyCount会给您面对Kinect的人数,然后将其替换为1,这样您的代码将变为:

this.bodies = new Body[1]; this.bodies = new Body [1];

I think usually the kinect will pick the closest person. 我认为通常kinect会选择最接近的人。 Try it and tell me what you get. 试试看,告诉我你得到了什么。

Instead of using a foreach to iterate the bodies array, just use the first body in the list. 无需使用foreach来迭代bodys数组,而只需使用列表中的第一个body。

Replace: 更换:

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

With: 附:

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

UPDATE: 更新:

I just tried this using Kinect Studio and I found that even when there is only one tracked body, it is not guaranteed to be in the first slot of the array. 我只是使用Kinect Studio进行了尝试,但我发现即使只有一个跟踪主体,也不能保证它位于数组的第一个插槽中。 In my app, for now I'm using LINQ to get the first body where IsTracked == true. 在我的应用程序中,现在我正在使用LINQ来获取IsTracked == true的第一个正文。 I don't have a good answer on how to do this for production ready code. 对于生产准备好的代码,我没有很好的答案。 If I solve this problem I'll update this post. 如果我解决了这个问题,我将更新这篇文章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM