Search code examples
wpfkinectkinect-sdk

Sensor only those which are in a particular area in front of kinect Xbox 360?


I have to create a Interactive menu board. I am using Kinect for Windows SDK v1.8. Till now by using its in built sample projects(Control basis - Wpf) I am able navigate (Control kinecttilebutton). When I start running the program and nobody is in the room it works Perfectly but if there is more than one person in front of the kinect sensor the the hand (Kinect Mouse Pointer) move here and there . Now my question
Is there any option kinect sensor only detect a person in a particular area (eg x=100-150,y=100-150,z=100-150)?

Edit

Here is come code where it process the skeleton data.

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

        using (SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame())
        {
            if (null != skeletonFrame)
            {
                try
                {
                    // Copy the skeleton data from the frame to an array used for temporary storage
                    skeletonFrame.CopySkeletonDataTo(this.skeletons);

                    var accelerometerReading = this.KinectSensor.AccelerometerGetCurrentReading();

                    // Hand data to Interaction framework to be processed
                    this.interactionStream.ProcessSkeleton(this.skeletons, accelerometerReading, skeletonFrame.Timestamp);
                }
                catch (InvalidOperationException)
                {
                    // SkeletonFrame functions may throw when the sensor gets
                    // into a bad state.  Ignore the frame in that case.
                }
            }
        }
    }

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.