문제

I am creating a WPF application to create digital catalog using kinect v1.8. I am trying to track only a single skeleton using following code:-

private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs skeletonFrameReadyEventArgs)
    {
        // Even though we un-register all our event handlers when the sensor
        // changes, there may still be an event for the old sensor in the queue
        // due to the way the KinectSensor delivers events.  So check again here.
        if (this.KinectSensor != sender)
        {
            return;
        }


        SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame();
        if (skeletonFrame == null)
            return;

        Skeleton[] skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
        skeletonFrame.CopySkeletonDataTo(skeletons);

        Skeleton skeleton = (from skl in skeletons
                             where skl.TrackingState == SkeletonTrackingState.Tracked
                             select skl).FirstOrDefault();

        if (skeleton == null)
            return;

        Skeleton[] s = new Skeleton[1];
        s[0] = skeleton;

        if (SkeletonTrackingState.Tracked == s[0].TrackingState)
        {
            //s1.SkeletonStream.ChooseSkeletons(s[0].TrackingId);
            var accelerometerReading = this.KinectSensor.AccelerometerGetCurrentReading();
            this.interactionStream.ProcessSkeleton(s, accelerometerReading, skeletonFrame.Timestamp);
        }
}

I am getting an exception when I run the code and skeleton gets detected as follows:-

InvalidOperationException

on the line "this.interactionStream.ProcessSkeleton(s, accelerometerReading, skeletonFrame.Timestamp);" I need to detect only one skeleton and use it for further processing like to access the digital catalog applications. Thanks in advance.

도움이 되었습니까?

해결책

I have Faced Same Problem By using below code I have track only one skeleton Which is closer to the sensor.and directly assign the closest skeleton to the main skeleton stream.

 private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs skeletonFrameReadyEventArgs)
    {
        Skeleton[] skeletons = new Skeleton[0];

        using (SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame())
        {
            if (skeletonFrame != null && this.skeletons != null)
            {
               //Console.WriteLine(skeletonFrame.SkeletonArrayLength);
                skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];

                // Set skeleton datas from skeletonFrame
                skeletonFrame.CopySkeletonDataTo(this.skeletons);

                TrackClosestSkeleton();
                Skeleton[] singleSkeleton = new Skeleton[6];

                Skeleton skl=(from mno in this.skeletons where mno.TrackingState==SkeletonTrackingState.Tracked && mno.TrackingId==globalClosestID select mno).FirstOrDefault();
                if (skl == null)
                    return;

                //Creating an empty skkeleton
                Skeleton emptySkeleton = new Skeleton();

                singleSkeleton[0] = skl;        //Pass the Tracked skeleton with closestID
                singleSkeleton[1] = emptySkeleton;  //Passing Empty Skeleton
                singleSkeleton[2] = emptySkeleton;  //Passing Empty Skeleton
                singleSkeleton[3] = emptySkeleton;  //Passing Empty Skeleton
                singleSkeleton[4] = emptySkeleton;  //Passing Empty Skeleton
                singleSkeleton[5] = emptySkeleton;  //Passing Empty Skeleton

                this.snew.SkeletonStream.ChooseSkeletons(globalClosestID);
                var accelerometerReading = this.KinectSensor.AccelerometerGetCurrentReading();
                this.interactionStream.ProcessSkeleton(singleSkeleton, accelerometerReading, skeletonFrame.Timestamp);

            }
        }
    }

int globalClosestID = 0;
    private void TrackClosestSkeleton()
    {
        if (this.snew != null && this.snew.SkeletonStream != null)
        {
            if (!this.snew.SkeletonStream.AppChoosesSkeletons)
            {
                this.snew.SkeletonStream.AppChoosesSkeletons = true; // Ensure AppChoosesSkeletons is set
            }

            float closestDistance = 10000f; // Start with a far enough distance
            int closestID = 0;

            foreach (Skeleton skeleton in this.skeletons.Where(s => s.TrackingState != SkeletonTrackingState.NotTracked))
            {
                if (skeleton.Position.Z < closestDistance)
                {
                    closestID = skeleton.TrackingId;
                    closestDistance = skeleton.Position.Z;
                }
            }

            if (closestID > 0)
            {
                this.snew.SkeletonStream.ChooseSkeletons(closestID); // Track this skeleton
                globalClosestID = closestID;
            }
        }
    }

check the above code it works for me.It may helpful to you.Here snew is the Kinectsensor.

다른 팁

You should try to track the closest skeleton using this method from MSDN

private void TrackClosestSkeleton()
  {
    if (this.kinect != null && this.kinect.SkeletonStream != null)
        {
        if (!this.kinect.SkeletonStream.AppChoosesSkeletons)
        {
        this.kinect.SkeletonStream.AppChoosesSkeletons = true; // Ensure AppChoosesSkeletons is set
        }

        float closestDistance = 10000f; // Start with a far enough distance
        int closestID = 0;

        foreach (Skeleton skeleton in this.skeletonData.Where(s => s.TrackingState != SkeletonTrackingState.NotTracked))
        {
        if (skeleton.Position.Z < closestDistance)
        {
          closestID = skeleton.TrackingId;
          closestDistance = skeleton.Position.Z;
        }
      }

      if (closestID > 0)
      {
        this.kinect.SkeletonStream.ChooseSkeletons(closestID); // Track this skeleton
      }
    }
  }

And then in your SkeletonFrameReady

private void SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            Skeleton[] skeletons = new Skeleton[0];

            using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
            {
                if (skeletonFrame != null && this.skeletonData != null)
                {
                    skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];

                    // Set skeleton datas from skeletonFrame
                    skeletonFrame.CopySkeletonDataTo(this.skeletonData);

                    TrackClosestSkeleton();
                }
            }
                //Do some stuff here
        }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top