Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top